当前位置: 首页 > 知识库问答 >
问题:

了解JWT的RSA签名

陆昊
2023-03-14

我正在JWT(JSON Web令牌)方案的帮助下实现一个登录系统。基本上,在用户登录/登录之后,服务器签署一个JWT并将其传递给客户机。

然后,客户机返回每个请求的令牌,服务器在发送回响应之前验证令牌。

这是你所期望的,但是我在这个过程的逻辑上遇到了一些问题。从我读过的所有数学文章来看,RSA签名似乎使用非对称密钥进行签名。由于公钥(顾名思义)是向客户机公开的,而私钥保留在服务器上,因此使用发送给客户机的公钥对JWT进行签名并在服务器端使用私钥进行验证是有意义的。

然而,在我看到的每一个例子和库中,似乎都是相反的。知道为什么会这样吗?如果一个JWT是用私钥签名并用公钥验证的,那又有什么意义呢?

共有1个答案

唐元青
2023-03-14

首先,抱歉,这个回答太长了。

如果您使用RSA对令牌进行签名,并且连接的客户端是web浏览器,则客户端将永远不会看到RSA密钥(公共或私有)。这是因为客户机大概不需要验证JWT是否有效,只有服务器需要这样做。客户端只需保留JWT并在请求时将其显示给服务器。然后服务器在看到令牌时进行检查以确保其有效。

那么为什么您可能需要JWT的公钥/私钥组合呢?首先,您不需要使用公钥/私钥算法。

您可以使用许多不同的算法签署JWT,RSA是其中之一。签署JWT的其他流行选择是ECDSA或HMAC算法(JWT标准也支持其他算法)。具体而言,HMAC不是一种公钥/私钥方案。只有一个密钥,即key,用于签名和验证令牌。您可以认为这是使用私钥来签名和验证JWT。无论如何,我不是这方面的专家,但以下是我最近做自己的研究得出的结论:

使用HMAC很好,因为它是最快的选择。然而,为了验证JWT,您需要给某人一个可以执行所有操作的密钥,与其他人共享这个密钥意味着该人现在也可以签署令牌并假装他们是您。如果您正在构建多个服务器应用程序,所有这些应用程序都需要能够验证您的JWT,那么您可能不希望每个应用程序都具有签名令牌的能力(不同的程序员可能维护不同的应用程序,与更多的人共享签名能力是一种安全风险,等等)。在这种情况下,最好有一个严格控制的私钥(和一个执行签名的应用程序),然后与其他人共享公钥,使他们能够验证令牌。在这里,私钥用于签署令牌,公钥用于验证令牌。在这种情况下,您需要选择RSA或ECDSA。

例如,您可能有一个应用程序生态系统,所有应用程序都连接到同一个数据库。为了让用户登录,每个应用程序都将用户发送到一个专用的“登录”应用程序。这个应用程序有私钥。其他应用程序可以验证用户是否使用公钥登录(但它们不能让用户登录)。

我所做的研究指出RSA是这种情况下大多数JWT应用程序的更好选择。这是因为,理论上,您的应用程序将经常验证令牌。RSA在验证方面比ECDSA快得多。ECDSA主要是因为按键的尺寸更小。这使得HTTPS证书更好,因为您需要将公钥发送到客户端的浏览器。但是在JWT场景中,密钥保留在服务器上,因此存储大小是N/a,验证速度更重要。

结论:如果你正在构建一个没有多个较小的“微服务应用程序”的小应用程序/你是唯一的开发者,那么可能选择HMAC来加密你的密钥。否则,很可能选择RSA。不过,我也不是专家,只是最近在谷歌上搜索过这个话题的人,所以我对此持半信半疑的态度。

 类似资料:
  • 为了理解数字签名和JWT是如何工作的,我尝试使用RS256算法验证JSON网络令牌。但是,当我解密JWT的签名部分时,它会给出非字符串值,因此我无法将该值与计算出的哈希值进行比较。有人能告诉我我在代码中误解了什么吗?我使用了RS256算法JWT令牌,所有的值都在https://jwt.io/.中给出。如果您向下滚动并选择RS256选项,您可以获得bas64url编码的JWT和公共/私钥。我想我解密

  • 在PHP中,我试图使用AWS的RSA公钥(我在https://cognito-identity.amazonaws.com/.well-known/jwks_uri). 密钥以适当的页眉/页脚开始,然后开始RSA公钥等等。我查看了一些PHP库,如Emarref\Jwt\Jwt\code>,但是我发现了错误:。这一切归结为基本的php函数:。 我已经研究了php。net/manual进行openss

  • 我想知道是否有一个示例C代码或库可以使用RSA公钥验证我的JWT令牌签名。我找不到任何涉及C的示例 openssl for C没有任何与RSA相关的示例。 谢谢

  • 我正在使用jose-jwt库,并希望使用RS256加密算法在C#中创建一个有签名的JWT。我对密码学没有经验,所以请原谅我的无知。我在文档中看到以下示例: 它显示了文件的使用,但是如何使用下面表单的RSA密钥文件呢?我正在查看X509Certificate2的文档,但我看不到RSA私钥的选项。它似乎只接受,我认为这是公钥。 最后,文档中列出的两个选项之间的区别是什么?我如何在这两个选项之间进行选择

  • 我已经使用Node rsa在Node中生成了一对私钥和公钥,并且可以在Node中使用这些密钥成功地进行签名和验证。 我尝试使用公钥的模和指数来验证中的签名(由节点中的私钥签名)。网 e、 g.我有一个string=“foo”,它有一个由Node生成的签名“abc123”。在里面NET我想使用公钥的模和指数来确认签名“abc123”对“foo”有效。 我想使用模数和指数而不是直接使用公钥的原因是因为

  • 问题内容: 我试图在Go项目的默认模板上使用GitHub上Go项目的CircleCI。 作为参考,这里的默认是什么 样子 : 作业运行时,我得到一个与代码本身完全无关的错误。 returned incorrect signature type There is no tracking information for the current branch. Please specify which