JWT 签名验证:HS256 与 RS256 的密钥怎么给
签名验证只做一件事:用密钥按 Token 头部声明的算法重算一遍签名,与第三段比对。一致说明内容没被改、且确实由持有密钥的一方签发;不一致就一个字符都别信。
两类算法,密钥形态完全不同
对称(HS256 / HS384 / HS512):HMAC。签发与验证用同一串共享密钥,随便一段字符串都行。优点是快、简单;缺点是任何能验证的人都能够签发——所以密钥只能在服务端之间共享,绝不能发到前端。
非对称(RS / PS / ES 系列):签发用私钥,验证用公钥。公钥可以公开分发,任何服务都能验证但不能签发。这是多方验证场景的正确选择。
页面会按所选算法切换对应的密钥输入框,避免把私钥填进 HMAC 那种「随便什么字符串都收」的框里。
密钥格式:PKCS#8 与 SPKI
- 私钥:PKCS#8,以
-----BEGIN PRIVATE KEY-----开头。 - 公钥:SPKI,以
-----BEGIN PUBLIC KEY-----开头。
老式的 -----BEGIN RSA PRIVATE KEY-----(PKCS#1)会被自动转换成 PKCS#8,所以从旧系统导出的私钥也能直接用。EC 私钥如果还是 SEC1 格式(-----BEGIN EC PRIVATE KEY-----),需要先转成 PKCS#8 再粘贴。
格式不对时提示会直接说明「密钥与算法不匹配」「缺少密钥」或「密钥解析失败」,而不是笼统地说验证失败。
验证失败的四种原因
- 密钥不对:HS 用了另一串密钥,或 RS 用了别人的公钥。
- 算法不匹配:Token 头部写 RS256,你按 HS256 验,结果必然不一致。
- 内容被改:有人改了 Payload 后重新编码,签名自然对不上。
- 编码差异:Token 在传输中被 URL 编码/换行折行,参与计算的实际字节变了。
前三条是真实的安全结论,第四条是数据在传输中坏了——先确认拿到的 Token 与原样一致,再判断密钥问题。
一个常见误用:把 alg 当真
算法是从 Token 头部读的,而头部是攻击者可改的。如果服务端「按 Token 说用什么算法就用什么算法」,攻击者可以把 alg 改成 none 或改成 HS256 并用公钥当 HMAC 密钥,从而绕过验证。
正确做法是服务端固定允许的算法列表,Token 头部声明的算法不在列表里就直接拒绝。验证工具本身不替你做这个判断,它只按你选的算法算。
上面这些都不用装软件,也不用注册:打开页面就能用。
打开 JWT 在线解析与签名验证生成 →常见问题
HS256 的密钥要多长?
至少与哈希输出等长(HS256 建议 32 字节以上)的随机串。短密码做密钥会被暴力破解,签名就失去意义。
RS256 和 PS256 有什么区别?
都是 RSA,填充方案不同。RS 用 PKCS#1 v1.5,PS 用 PSS(更现代、安全性论证更强)。新系统建议 PS256;老系统兼容性考虑用 RS256。
ES256 的签名长度是多少?
64 字节(r 与 s 各 32 字节),base64url 后 86 个字符。注意 JWS 要求的是原始 r||s 拼接,不是 DER 编码,两者长度不同。