alg 头决定一切

一个 的头部指明用于签名它的算法,例如 "alg": "HS256"。那一个值决定了验证者需要何种密钥,以及签名实际证明了什么。这些算法分为两个族,对称与非对称,而在两者之间的选择,其实是关于谁需要验证该令牌的选择。

对称:HMAC 族(HS256/384/512)

HS256HS384HS512 是采用 SHA-384 或 SHA-512 的 。它们对签名与验证都使用一个共享秘密。能验证一个 令牌的人,也能伪造一个,因为创建与核对签名使用同一个密钥。

这使 HMAC 族在同一方既签发又验证令牌时、或当签发者与验证者已共享一个受信任的秘密时(例如一个单一后端签署它自己的会话令牌),成为一个不错的选择。它快速而简单。它的局限在于分发:每个验证者都需要该秘密,而秘密栖身的地方越多,一旦一个泄露,波及半径就越大。

非对称:RSA 与 ECDSA(RS256、ES256 及更多)

RS256(采用 SHA-256 的 RSASSA-PKCS1-v1_5)、PS256)和 ES256(采用 P-256 曲线的 )使用一个密钥对:一个私钥签名,相应的公钥验证。私钥从不离开签发者;公钥可以交给任何人。

许多独立服务必须验证来自一个签发者的令牌时,这正是你想要的。一个身份提供方用其私钥签名,并发布其公钥(通常作为一个 端点);每个下游服务用公钥验证,而它们谁都不能铸造令牌。这就是为什么 OpenID Connect 提供方默认签发 的 ID 令牌。

ECDSA 之间,取舍是大小与速度:在同等安全下,ECDSA 的密钥与签名要小得多,而 RSA 更古老、得到更普遍的支持。EdDSA(Ed25519)是一个正在获得采用的现代、快速的替代品。

选择

  • 一方既签名又验证,或一个秘密已被共享HMACHS256)。简单而快速。
  • 一个签名方,许多独立的验证者 → 非对称(RS256ES256)。公钥可自由分发;唯有私钥的持有者能签名。

无论你选什么,验证者都必须固定可接受的算法,而非信任令牌自己的 alg 头。接受令牌所声称的任何东西,会为 JWT 解剖一文所述的 alg: none 与算法混淆攻击敞开大门。

JWT 工具 解码头部,使你能看到一个令牌声明了哪种算法,并针对你粘贴的一个秘密验证 HMAC 族(HS256/384/512),在你的浏览器中本地进行。