You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级io.jsonwebtoken至0.11.2后旧JWT无法通过Key解析问题咨询

问题根因

不兼容问题核心是JJWT不同版本对signWith方法传入字符串参数的处理逻辑差异,以及构造Key对象时的参数错误:

  • 旧版本signWith(SignatureAlgorithm, String)方法隐含逻辑:默认将传入的字符串视为Base64编码后的密钥,会自动先做Base64解码,再用解码后的原始字节作为实际签名密钥
  • 当前构造SecretKeySpec的错误逻辑:直接使用secretKeyEncoded.getBytes()作为入参,这是把Base64编码后的字符串的原始字符字节当成了密钥,和旧版本实际使用的签名密钥完全不一致,自然无法解析旧版本生成的JWT
修复方案

构造Key对象时,先对Base64编码的密钥字符串做解码,再生成密钥对象即可兼容旧有已签发的JWT,正确代码如下:

private final String secretKeyEncoded = Base64.getEncoder().encodeToString(secretKey.getBytes());

// 正确构造Key:先解码Base64字符串,再生成SecretKeySpec
byte[] decodedKeyBytes = Base64.getDecoder().decode(secretKeyEncoded);
Key key = new SecretKeySpec(decodedKeyBytes, SignatureAlgorithm.HS256.getJcaName());

// 旧版本生成的JWT现在可以正常解析
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(originalJWT); // 此时可正常运行

// 新版本签发JWT逻辑不变,生成的新JWT也用同一个Key即可正常解析
final String newJWT = Jwts.builder()
        .setClaims(claims)
        .setIssuedAt(now)
        .setExpiration(validity)
        .signWith(key, SignatureAlgorithm.HS256)
        .compact();
额外注意事项

如果旧代码中传入signWith的字符串是未经过Base64编码的原始密钥字符串,那么构造Key时不需要做Base64解码,直接使用原始字符串的字节数组生成SecretKeySpec即可:

// 旧密钥是原始字符串未做Base64编码的场景
Key key = new SecretKeySpec(originalSecretStr.getBytes(StandardCharsets.UTF_8), SignatureAlgorithm.HS256.getJcaName());

内容的提问来源于stack exchange,提问作者UnnameDSoS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 05:06:05