文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JWT:我应该使用哪种签名算法?

2024-12-14 00:48

关注

JWT:我应该使用哪种签名算法?

JSON Web Token (JWT) 可以使用许多不同的算法进行签名:RS256、PS512、ES384、HS1;当被问及他们想使用哪一个时,您就会明白为什么有些开发人员会挠头。

根据我的经验,许多主流身份提供商历来只提供 RS256 或至少默认使用它。然而,由于开放银行等举措,这些身份提供商现在正在扩大他们的支持以涵盖更多签名算法,这意味着您需要开始了解要使用哪些算法。

我不是密码学家,但通过与 OpenID Connect 和 FIDO2 的合作,我获得了从业者对各种签名算法的理解以及密码学社区对每种算法的总体感受。在本文中,我将为您提供一些知识,以便您了解每个“alg”值的含义并选择可用的最佳签名算法。

TL;DR: EdDSA > ECDSA 或 RSASSA-PSS > RSASSA-PKCS1-v1_5 并且知道会发生什么。

算法 (alg) 值

在我们查看每个签名算法系列之前,让我们首先澄清我们所说的“alg”值(例如 RS256)的含义。这些是 JSON Web 算法 (JWA),它们是 JavaScript 对象签名和加密 (JOSE) 系列的一部分。您将在 JWT 标头中看到“alg”值,告诉您 JWT 是如何签名的,在 JSON Web Keys (JWK) 中,告诉您密钥用于什么算法。

作为一般经验法则,“alg”值可以分解为:

RS

256

签名算法

散列算法

大多数签名算法都有 SHA-256、SHA-384 和 SHA-512 的变体。在某些情况下,您甚至可以使用“RS1”之类的东西,它使用 SHA-1 ?? 并且是 FIDO2 一致性所必需的。

这些算法通常在RFC 7518 中[1]定义,但您可以在JOSE IANA 注册表中[2]找到受支持算法的完整列表。

我应该使用哪种散列算法?

SHA-256、SHA-384 和 SHA-512 都是相同散列算法系列的变体:SHA-2。

根据经验,算法中的数字是指它将生成的散列的大小。例如,SHA-256 将产生一个 256 位的哈希值,而 SHA-512 将产生一个 512 位的哈希值。

每个给您的安全级别是其输出大小的 50%,因此 SHA-256 将为您提供 128 位的安全性,而 SHA-512 将为您提供 256 位的安全性。这意味着攻击者在开始寻找冲突之前必须生成 2^128 个哈希值,这要归功于生日界限[3]。这就是我们使用最少 128 位安全性的原因。

很快您就不会需要比 SHA-256 更好的东西了。只是不要使用 SHA-1。

验证:了解您的算法

每个应用程序验证JWT签名应该事先知道算法的期望和准确使用哪个键。您可以通过将每个公钥分配给一个算法来实现(例如,此密钥用于 RS384,此密钥用于 ES256)。当单个算法有多个密钥时,您可以使用kidJWT 标头中的密钥 ID ( ) 来了解要使用哪个。

基本上,您要确保JWT 中的kid和alg值符合您的期望。如果他们不匹配,那么有人就不好了。

  1.     "typ""JWT"
  2.     "kid""123", // is this key... 
  3.     "alg""RS256" // ...allowed to be used for this algorithm? 

OpenID Connect 等协议使用发现文档和受 TLS 保护的端点上可用的 JSON Web 密钥集 (JWKS) 来促进这一点。

现在,你不应该只相信 JWT 标头中的“alg”值,也不应该接受带有“none”算法的 JWT 或在其标头中嵌入公钥的 JWT。

RSASSA-PKCS1-v1_5 (例如 RS256)

RS256 = RSASSA-PKCS1-v1_5 使用 SHA-256

虽然 RS AES -PKCS1-v1_5 对于加密不再安全,但 RSA SSA -PKCS1-v1_5 仍然适用于数字签名。正如我之前提到的,根据我的经验,RS256 历来是大多数 JWT 实现的默认值,许多 SaaS 身份提供商只提供这种签名算法。很难找到一个系统不支持用 RS256 签名的 JWT。

使用 RSASSA-PKCS1-v1_5 签名的 JWT 具有确定性签名,这意味着相同的 JWT 标头和有效负载将始终生成相同的签名。

RSASSA-PKCS1-v1_5 已经存在很长时间了,但是现在,您通常应该更喜欢 RSASSA-PSS(具有概率签名的 RSA)。这并不是说 RSASSA-PKCS1-v1_5 被破坏了,而是说 RSASSA-PSS 只是具有其他人没有的理想功能。事实上,RFC 8017 现在在使用 RSA 进行签名时将 RSASSA-PSS 视为一项要求:

尽管没有已知针对 RSASSA-PKCS1-v1_5 的攻击,但为了提高健壮性,新应用程序中需要 RSASSA-PSS。

RFC 8017[4]

话虽如此,在讨论Bleichenbacher[5]对 RSA PKCS#1 加密和签名标准的攻击[6]时,Real-Word Cryptography 中的[7]David Wong分享了一个有趣的统计数据:

与完全破坏加密算法的第一次攻击不同,第二次攻击是实现攻击[针对签名验证]。这意味着如果签名方案被正确实现(根据规范),攻击就不会起作用。

然而,2019 年[8]表明,许多用于签名的 RSA PKCS#1 v1.5 开源实现实际上陷入了该陷阱并错误地实施了标准,这使得 Bleichenbacher 的伪造攻击的不同变体得以发挥作用!

真实世界密码学[9]

由于攻击是针对签名验证的,因此您必须确信所有验证您的 JWT 的收件人都在使用不易受到 Bleichenbacher 攻击的库。如果您要与许多第 3 方打交道,那将很困难。

围绕开放银行的工作,例如 OpenID 的金融级 API (FAPI),不允许使用 RSASSA-PKCS1-v1_5。对于我的普通读者,这是 IdentityServer 中唯一可用的算法,直到 IdentityServer4 版本 3。

进一步阅读

了解如何使用 OpenSSL 为 JWT 签名生成 RSA 密钥[10]

RSASSA-PSS (例如 PS256)

PS256 = RSASSA-PSS 使用 SHA-256 和 MGF1 和 SHA-256

RSASSA-PSS 是 RSA 的概率版本,其中相同的 JWT 标头和有效负载每次都会生成不同的签名。与其他算法不同,这是一种很好的概率方法;虽然在签名生成期间可以使用随机值,但它对安全性并不重要。一般来说,它的实现要简单得多,因此更难出错。

如果您想使用 RSA 密钥,那么建议您使用 RSASSA-PSS 而不是 RSASSA-PKCS1-v1_5,但幸运的是,RSA 密钥可用于任一签名方案。两者之间的签名长度也相同。

英国的开放银行最初强制要求使用 PS256,但后来将其开放至 ES256。

进一步阅读

ECDSA (例如 ES256)

ES256 = ECDSA 使用 P-256 和 SHA-256

在椭圆曲线数字签名算法 (ECDSA) 的情况下,ES256 中引用散列算法的数字也与曲线有关。ES256 使用 P-256(secp256r1,又名 prime256v1),ES384 使用 P-384(secp384r1),而奇怪的是,ES512 使用 P-521(secp521r1)。是的,521。是的,连微软[13]都打错了。

椭圆曲线加密 (ECC) 比 RSA 更难破解(或者我们可能真的很擅长破解 RSA)。因此,ECDSA 可以使用比 RSA 短得多的密钥和短得多的签名。大约 256 位的短椭圆曲线 (EC) 密钥提供与 3072 位 RSA 密钥相同的安全性。

您经常会看到 ECDSA 被列为比 RSA 中的等效项更快,但这仅适用于签名生成;使用 RSA 进行签名验证通常仍然更快。使用 JWT,您很可能会进行一次签名并进行多次验证。

使用 ECDSA 签名的 JWT 具有概率签名,这意味着相同的 JWT 标头和有效负载将始终生成不同的签名。但不幸的是,ECDSA 以一种糟糕的方式是概率性的,其中随机生成对签名的安全性至关重要。

ECDSA 使用每个签名生成的随机数(不超过一次)。未能只使用一次随机数值会使私钥很容易恢复,这在索尼的 Playstation 3 和比特币中[14]都已经出现过。在 Playstation 3 中,私钥因静态随机数而被恢复,而在比特币中,Android 用户因 Android 上 Java 的 SecureRandom 类中的错误而受到影响。如果概率签名的安全性需要随机值,那么您应该更喜欢不需要的确定性签名。

RSASSA-PKCS1-v1_5 在签名验证方面存在问题,而 ECDSA 在签名生成方面存在问题,当您是令牌发行者时,这更容易处理。

ECDSA 越来越受欢迎,但由于椭圆曲线加密的实施方式,密码学家似乎普遍反对,并担心由于使用随机值而导致实施困难。它比 RSA 享有更好的声誉,但密码学家仍然主张迁移到 EdDSA。

JOSE 最初使用的曲线由 NIST 定义。如果您担心使用由 NIST 定义的曲线但想要使用 ECDSA,则一种流行的替代方法是使用 Koblitz 曲线,例如 secp256k1(与 secp256r1 相对)。Kobiltz 曲线稍微弱一些,但如果您担心 NIST 曲线中使用的无法解释的随机数表明另一个 NSA 后门,那么 Kobiltz 曲线提供了一个越来越受欢迎的替代方案。您可以在比特币、以太坊和 FIDO2 中找到这些曲线的用法。但是,如果您想使用非 NIST 曲线,您应该使用 EdDSA。在 JOSE 中,使用 Kobiltz 的算法以 K 结尾,例如 ES256K。

进一步阅读

EdDSA

EdDSA = 使用了 EdDSA 签名算法

EdDSA 与之前算法的趋势相反,使用单一alg值。相反,它依赖于crv预先商定的密钥中定义的曲线 ( )。

例如,包含 EdDSA 公钥的 JWK 将如下所示:

  1.   "kty""OKP"
  2.   "alg""EdDSA"
  3.   "crv""Ed25519"
  4.   "x""60mR98SQlHUSeLeIu7TeJBTLRG10qlcDLU4AJjQdqMQ" 

这迫使现代行为使用分配给密钥的曲线,而不是 JWT,并消除了各种alg相关的攻击。

EdDSA 是一种椭圆曲线密码学形式,它利用了扭曲的 Edwards 曲线。它是 Schnorr 签名系统(而不是 DSA)的变体。 EdDSA 在签名和验证方面都很快,签名很短,并且可以避开所有类别的安全漏洞。

RFC 8037 定义了 JOSE 对以下 EdDSA 变体的支持:

使用 EdDSA 签名的 JWT 具有确定性签名,这意味着相同的 JWT 标头和有效负载将始终生成相同的签名。这是一种确定性的好方法,解决了依赖随机 nonce 值来保护私钥的问题。EdDSA 仅在私钥创建期间使用随机值。这是JOSE 和 JWT 的批评者推荐[19]的算法。

JWT 库中对 EdDSA 的支持有点参差不齐,但预计很快就会看到更多的 EdDSA。

进一步阅读

HMAC (例如 HS256)

HS256 = HMAC 使用 SHA-256

到目前为止,我们一直在谈论非对称密码学,其中只有令牌发行者拥有创建签名的私钥,而其他所有人都拥有可用于验证签名的相应公钥。例如,身份提供者拥有私钥,依赖方使用公钥。

在极少数情况下,您将是唯一发行和验证令牌的人,那么您可以考虑使用对称密码术和 HS256 之类的东西。 这使用相同的密钥来创建和验证签名。

在我看来,如果你发现自己处于这个位置,那么我认为 JWT 不是适合你的解决方案。如果同一个实体同时进行读取和写入,那么在 JWT 中对结构化、明文数据进行往返的要求是什么?我建议将数据存储在数据库中并传递引用或使用诸如 Branca 令牌或 JSON Web 加密 (JWE) 之类的东西来确保只有您可以读取数据。

通常,使用 HMAC 进行 JWT 签名被视为一种反模式。

进一步阅读

不使用任何加密?!

无 = base64 加密 编码

对不起,我忍不住了。请不要使用这个。

建议

尽可能使用 EdDSA,否则使用 ECDSA。 如果您被迫使用 RSA,则更喜欢 RSASSA-PSS 而不是 RSASSA-PKCS1-v1_5。

我不认为说 RSA 正在缓慢退出是一个有争议的声明。目前,提供 ECDSA 是一个不错的选择,但理想情况下,您会希望尽可能使用 EdDSA。

但是,无论您使用哪种算法,请确保提前知道期望使用哪种算法以及使用哪个密钥进行验证。

References

[1] RFC 7518 中: https://tools.ietf.org/html/rfc7518

[2] JOSE IANA 注册表中: https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms

[3] 生日界限: https://en.wikipedia.org/wiki/Birthday_attack

[4] RFC 8017: https://tools.ietf.org/html/rfc8017

[5] Bleichenbacher: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher

[6] 的攻击: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher

[7] Real-Word Cryptography 中的: https://www.manning.com/books/real-world-cryptography

[8] 2019 年: https://www.cs.purdue.edu/homes/schau/files/pkcs1v1_5-ndss19.pdf

[9] 真实世界密码学: https://www.manning.com/books/real-world-cryptography

[10] 生成 RSA 密钥: https://www.scottbrady91.com/OpenSSL/Creating-RSA-Keys-using-OpenSSL

[11] RSASSA-PSS 以及如何在 .NET Core 中使用它的: https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-RSASSA-PSS-in-dotnet-Core

[12] 生成 RSA 密钥: https://www.scottbrady91.com/OpenSSL/Creating-RSA-Keys-using-OpenSSL

[13] 连微软: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/master/src/Microsoft.IdentityModel.Tokens/JsonWebKeyECTypes.cs#L40

[14] 索尼的 Playstation 3 和比特币中: https://medium.com/asecuritysite-when-bob-met-alice/not-playing-randomly-the-sony-ps3-and-bitcoin-crypto-hacks-c1fe92bea9bc

[15] 如何在 .NET Core 中使用 ECDSA: https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-ECDSA-in-dotnet-Core

[16] 在 IdentityServer4 中使用 ECDSA 签署令牌: https://www.scottbrady91.com/Identity-Server/Using-ECDSA-in-IdentityServer4

[17] 生成 EC 密钥: https://www.scottbrady91.com/OpenSSL/Creating-Elliptical-Curve-Keys-using-OpenSSL

[18] 以及使用 Kobiltz 曲线的示例: https://www.scottbrady91.com/C-Sharp/Supporting-Custom-JWT-Signing-Algorithms-in-dotnet-Core

[19] JOSE 和 JWT 的批评者推荐: https://www.scottbrady91.com/JOSE/Alternatives-to-JWTs

[20] EdDSA 以及如何在 .NET Core 中使用它的: https://www.scottbrady91.com/C-Sharp/EdDSA-for-JWT-Signing-in-dotnet-Core

[21] 开始使用 EdDSA: https://github.com/scottbrady91/IdentityModel

[22] ScottBrady.IdentityModel 进行 JWT 签名: https://github.com/scottbrady91/IdentityModel

[23] cr.yp.to 上: https://ed25519.cr.yp.to/

[24] JWE 以及如何在 .NET Core 中使用它们: https://www.scottbrady91.com/C-Sharp/JSON-Web-Encryption-JWE-in-dotnet-Core 

[25] 如何将 Branca 令牌: https://www.scottbrady91.com/C-Sharp/Replacing-JWTs-with-Branca-and-PASETO-in-dotnet-Core

 

来源: DotNET技术圈内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯