了解 JWT 的 RSA 签名 [英] Understanding RSA signing for JWT

查看:18
本文介绍了了解 JWT 的 RSA 签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 JWT(JSON Web Token)方案的帮助下实现了一个登录系统.基本上,在用户登录/登录后,服务器对 JWT 进行签名并将其传递给客户端.

I'm implementing a sign in system with the help of the JWT (JSON Web Token) scheme. Basically, after a user sign in / login, the server signs a JWT and passes it to the client.

然后客户端在每个请求中返回令牌,服务器在发回响应之前验证令牌.

The client then returns the token with each request and the server verifies the token before sending back a response.

这几乎是您所期望的,但我在流程的逻辑上遇到了一些问题.从我读过的所有数学文章中,似乎 RSA 签名使用非对称密钥进行签名.顾名思义,公钥向客户端公开,而私钥保存在服务器上,因此使用发送给客户端的公钥对 JWT 进行签名并在服务器端使用验证它是有意义的私钥.

This is pretty much how you would expect it, but I'm having some problems with the logic of the process. From all the mathematical articles I've read, it seems that RSA signing uses asymmetric keys for signing. As the public key, as its name suggests, is exposed to the client and the private key is kept on the server, it makes sense to sign the JWT with the public key which is sent to the client and verify it on the server side using the private key.

但是,在我看到的每个示例和库中,情况似乎是相反的.知道为什么会这样吗?如果 JWT 使用私钥签名并使用公钥进行验证,那还有什么意义?

However, on every example and library I see it seems to be the other way around. Any idea as to why it is so? If a JWT is signed with the private key and verified with the public one than whats the point?

推荐答案

首先,抱歉,这个答案有点长.

First off, apologies, this answer got rather long.

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

If you use RSA to sign your tokens, and a connecting client is a web browser, the client will never see the RSA keys (public or private). This is because the client presumably doesn't need to verify that the JWT is valid, only the server needs to do that. The client just holds onto the JWT and shows it to the server when asked. Then the server checks to make sure its valid when it see's the token.

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

So why might you need a public / private key combo for JWT's? Well first off, you don't need to use a public / private key algorithm.

您可以使用多种不同的算法签署 JWT,RSA 就是其中之一.签署 JWT 的其他流行选择是 ECDSA 或 HMAC 算法(JWT 标准支持 其他以及).具体来说,HMAC 不是公钥/私钥方案.只有一个密钥,密钥,用于对令牌进行签名和验证.您可以将其视为使用私钥对 JWT 进行签名和验证.无论如何,我都不是这方面的专家,但这是我最近通过自己的研究得出的结论:

You can sign JWT's with a number of different algorithms, RSA being one of them. Other popular choices for signing your JWT's are ECDSA or HMAC algorithms (the JWT standard supports others as well). HMAC, specifically, is not a public / private key scheme. There's just one key, the key, which is used to both sign and validate the tokens. You can think of this as using the private key for both signing and validating the JWT's. I'm not an expert on this by any means, but here's the conclusions I came to from doing my own research recently:

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

Using HMAC is nice because it's the fastest option. However, in order to validate the JWT's, you need to give someone the one key that does everything, Sharing this key with someone else means that that person could now also sign tokens and pretend like they're you. If you're building multiple server applications that all need to be able to validate your JWT's, you might not want every application to have the ability to sign tokens as well (different programmers might be maintaining the different applications, sharing the signing ability with more people is a security risk, etc). In this case, it's better to have one, tightly controlled private key (and one app that does the signing) and then share the public key around with other people to give them the ability to validate the tokens. Here, the private key is used for signing the tokens, and the public key is used for validating them. In this case you'd want to choose RSA or ECDSA.

例如,您可能拥有一个应用生态系统,这些应用都连接到同一个数据库.为了让用户登录,每个应用程序都会将人们发送给一个,专用的登录"应用程序.这个应用程序有私钥.另一个应用程序可以使用公钥验证此人是否已登录(但他们无法让人们登录).

As an example, you might have an ecosystem of apps that all connect to the same database. To log users in, each app sends folks to one, dedicated, 'logging in' app. This app has the private key. The other apps can verify that the person is logged in using the public key (but they can't log people in).

我所做的研究表明,在这种情况下,对于大多数 JWT 应用来说,RSA 是更好的选择.这是因为从理论上讲,您的应用会频繁地验证令牌.RSA 在验证方面比 ECDSA 快得多.ECDSA 主要是因为密钥的大小更小.这使得 HTTPS 证书更好,因为您需要将公钥发送到客户端的浏览器.但在 JWT 场景中,密钥保留在服务器上,因此存储大小为 n/a,验证速度更为重要.

The research I've done points to RSA being the better option for most JWT apps in this scenario. This is because your app will be, theoretically, validating tokens frequently. RSA is much faster then ECDSA at verification. ECDSA is primarily nice because the keys are smaller in size. This makes it better for HTTPS certificates because you need to send the public key to the client's browser. In the JWT scenario though, the keys are staying on a server so the storage size is n/a and the verification speed is more important.

结论:如果您正在构建一个没有多个较小微服务应用程序"的小型应用程序/您是唯一的开发人员,则可能选择 HMAC 来加密您的密钥.否则,可能会选择 RSA.再说一遍,我不是专家,只是最近在谷歌上搜索过这个主题的人,所以对此持保留态度.

Conclusion: if you're building a small app without multiple smaller 'micro-service apps' / you're the only developer, probably choose HMAC to encrypt your keys. Otherwise, probably choose RSA. Again though, I'm not an expert, just someone who recently googled this topic, so take this with a grain of salt.

这篇关于了解 JWT 的 RSA 签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆