在 RESTful API 的上下文中,使用 RSA 签署 JWT 比 SHA 有啥优势?

Posted

技术标签:

【中文标题】在 RESTful API 的上下文中,使用 RSA 签署 JWT 比 SHA 有啥优势?【英文标题】:What advantage does signing a JWT with RSA have over SHA in the contect of a RESTful API?在 RESTful API 的上下文中,使用 RSA 签署 JWT 比 SHA 有什么优势? 【发布时间】:2020-07-09 06:25:25 【问题描述】:

我有一个后端,它公开了一个 RESTful API,它目前“对所有人免费”(但使用 https)。

我现在想添加 RBAC(基于角色的访问控制),而 JWT 似乎是可行的方法,我阅读了很多有关 JWT 的信息,但没有看到使用 RSA 而非 SHA 签署令牌的优势。

假设用户已经通过身份验证并获得了一个密钥,无论是共享的还是公共/私有的。

现在,在我看来,在这两种情况下 - SHA 或 RSA HMAC - 双方(客户端和服务器)都必须拥有共享密钥,或者在 RSA 的情况下它们的私钥/公钥的一半。并且服务器必须根据 JWT 中的声明找到该密钥(在表或数据库中),以验证令牌的签名。一旦它在 JWT 中确认了声称的用户,它将使用配置的角色授权请求。

那么 RSA 在这种情况下的优势是什么?

【问题讨论】:

【参考方案1】:

我假设您在这里谈论的是 RSxxx(例如 RSA256)和 HSxxx(例如 HS256 (HMAC-SHA256))算法。主要区别在于 HS256 是一种对称算法,而 RS256 是一种非对称算法。对称算法只使用一个密钥(或秘密)进行签名和验证,而非对称算法使用私钥签名,公钥验证令牌。

如果您共享用于 HS256 的密钥,则知道该密钥的每个人都可以发布或修改并重新签署令牌。如果您与客户共享秘密,那将破坏签名的目的。对于 RS256 或任何其他非对称算法,只有认证服务器知道私钥,任何需要验证令牌的人都可以使用公钥进行验证。匹配的密钥通常由令牌标头中的 KID(密钥 ID)声明标识。

但通常,签名和验证只在服务器端完成,客户端不需要验证令牌,因此根本不需要知道密钥或秘密。因此,您可以在一个简单的服务的情况下,当身份验证和资源服务器相同时,仍然依赖对称算法。但是,一旦您为多个资源服务器设置了一个单独的身份验证服务器,就应该使用非对称算法。

【讨论】:

【参考方案2】:

感谢您的回复,这确实有助于使其更清晰。

所以基本上,对于一个简单的 RESTful API,使用 RSA 相对于 HSA 并没有真正的优势。


关于基于令牌的身份验证可能对其他人有所帮助的几点:

序言:以下都是使用 SSL 的上下文。

首先,令牌是用户名/密码凭据的替代品:如果客户端有令牌,则相当于拥有用户名/密码。我花了一段时间才弄明白。有点像在公司打印机上使用徽章:无需输入用户名和密码,您只需将徽章(令牌)放在打印机上,它就会知道您是谁并打印您的文档。

但是,令牌使 API 的使用更加简单,因为

客户端只需将其令牌添加到 http 标头中, 服务器只验证令牌, 无需处理涉及用户名/密码和管理会话 cookie 的身份验证流程。

但缺点是

丢失令牌就像丢失用户名/密码,并且 在涉及许多组件的复杂系统中,令牌必须在所有涉及的后端服务器之间共享。

其次,客户并不严格需要验证令牌 - 它只需要令牌 - 如果有人给你他们房子或汽车的钥匙,你通常不会检查钥匙,你信任这个人(也许有时很愚蠢)并使用它。所以一个简单的随机字符串可以作为一个令牌;服务器维护一个简单的表,将令牌与用户关联起来,根本不涉及任何密钥。如果客户端发送服务器没有的令牌 -> 访问被拒绝。如果它有匹配的令牌 --> 查找与令牌相关的用户(通常后跟授权)。

第三,服务器通常基于信任客户端生成令牌,或者在客户端以某种方式进行身份验证后生成令牌,例如 .誓言。之后,客户端只需将令牌与每个请求一起发送,服务器就会在其表中查找它。但是,用于随机字符串令牌的此类服务器端表可能会变得很大并且必须是持久的,因此需要数据库或文件,并且它们通常比较慢,需要维护等,因此使用加密签名和 jwt 输入:

四、带签名的token:

服务器签署令牌并将其发送给客户端 - 但服务器不必存储它,也没有如上所述的会话 cookie 客户端安全地存储令牌并在每个后续请求中发送它(就像使用随机字符串令牌一样) 服务器收到请求,计算jwt的签名,与客户端发送的token的签名进行比较。请注意,没有文件或数据库查找,只是再次计算签名并将其与客户端发送的签名进行比较。如果签名匹配,则令牌必须与服务器发出的令牌相同,因此 jwt 标头和有效负载也与服务器发出的相同 服务器现在解释有效载荷,特别是。用户(通常执行授权)

所以,使用 jwt 意味着服务器不需要

包含用户名和令牌的数据库或文件 保存令牌 维护会话 cookie

它只需要创建和比较一个签名。为此,它需要一个加密密钥。这可以是用于简单 API 的对称密钥,也可以是用于必须共享公钥的更复杂系统的非对称密钥。

希望这可以帮助其他一些正在努力解决这个问题的人。

【讨论】:

....但是服务器保存令牌可能还有其他原因,例如撤销。

以上是关于在 RESTful API 的上下文中,使用 RSA 签署 JWT 比 SHA 有啥优势?的主要内容,如果未能解决你的问题,请参考以下文章

RESTful API - 批量操作的分块响应

如何设计好的RESTful API

如何设计好的RESTful API

Rest在Dubbo中开发REST风格的远程调用(RESTful Remoting)

Rails 中的 RESTful DCI 上下文

使用JAX-RS创建RESTful Web Service