🔐 JWT 算法混淆(Algorithm Confusion)不是“密钥泄露”,而是验证器把不同算法当成一回事

JWT 看起来只是三段 Base64 文本,真正危险的地方不在“能不能看懂 payload”,而在服务端怎么验签。算法混淆的经典问题是:开发者本来想用 RS256 这种“私钥签名、公钥验证”的非对称方案,结果验证库却信了 token 头里的 alg,被攻击者改成 HS256。这样一来,服务端原本公开给大家的 RSA 公钥,反而会被当成 HMAC 的“对称密钥”来验签。攻击者拿得到公钥,就能自己伪造一个“合法”管理员 token。

这事为什么会发生?因为很多人把“算法类型”和“密钥类型”分开想了。库如果写得松,流程就会变成“先读 token 头,看它说自己是什么算法,再拿你给我的 key 去试着验”。这就是烂设计:把安全决策交给了攻击者可控的输入。好一点的实现应该反过来,服务端先固定这个接口只接受 RS256,再用 RSA 公钥按 RS256 去验;token 头里的 alg 只能拿来做一致性检查,不能拿来决定验证路径。

现实里的防法也很直接。第一,不要接受客户端声明算法,服务端把允许的算法白名单写死。第二,别把“一个 key 对象”同时喂给多种算法路径,更不要让 RSA 公钥有机会落到 HMAC 验证器里。第三,拒绝 alg=none,也拒绝算法和 key 类型不匹配的情况。第四,升级 JWT 库,很多老漏洞本质上是库默认行为太宽松。最后,鉴权不能只看“签名过了”,还要继续校验 issaudexp 和用途,不然你只是把另一种伪造票据放进系统。

🧪 你在审一个登录网关,发现代码写的是“从 JWT 头读取 alg,然后把配置里的 public_key.pem 传给通用 verify() 函数”。现在系统号称使用 RS256。攻击者最可能怎么打?
alg

💡 核心记忆:JWT 的算法选择权绝不能交给 token 头,服务端必须先定算法,再验签。

#Security