Spring Boot用JJWT v0.12生成HS256签名JWT遇权限错误
JJWT v0.12签名HS256 JWT报错的原因及解决办法
核心结论
大概率是你密钥的生成/使用方式不符合JJWT v0.12的规范,而非库的内部实现问题。v0.12对密钥的合法性要求比v0.11.5严格很多,这是导致报错的根本原因。
具体分析
密钥长度要求变化
JJWT v0.12强制遵循JWT标准:HS256算法要求密钥长度至少为256位(也就是32字节)。而v0.11.5对短密钥做了兼容处理——哪怕你用16字节的字符串当密钥,它也会自动让JCA的HmacSHA256算法处理(只是安全性大打折扣)。如果你的base64密钥解码后长度不足32字节,就会触发底层签名失败,而日志里的sun.security.util.KeyUtil访问问题只是这个核心错误的表象。密钥处理方式错误
如果是按官方文档生成的base64密钥,但读取时没有正确还原成SecretKey对象,而是直接用字符串转字节数组,也会导致密钥不合法。v0.12要求必须用标准的密钥对象签名,不能像v0.11.5那样直接传字符串。
正确的使用步骤
1. 生成合规的HS256密钥
用JJWT提供的工具类生成符合要求的密钥,再转成base64字符串存配置:
// 生成256位的SecretKey SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256); // 转成base64字符串,存入配置文件 String base64Key = Encoders.BASE64.encode(secretKey.getEncoded());
2. 从配置读取并还原密钥
在代码中读取配置的base64字符串,还原成SecretKey后再用于签名:
// 从配置文件读取base64密钥 String base64Key = yourConfig.getJwtSecret(); // 还原成SecretKey SecretKey secretKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64Key));
3. 生成JWT示例
String jwt = Jwts.builder() .subject("user123") .expiration(new Date(System.currentTimeMillis() + 3600000)) // 1小时过期 .signWith(secretKey, SignatureAlgorithm.HS256) .compact();
验证密钥合法性
如果还是报错,先检查你的base64密钥解码后的字节长度:
byte[] keyBytes = Decoders.BASE64.decode(base64Key); System.out.println("密钥字节长度:" + keyBytes.length); // 必须≥32
如果长度不足,重新生成合规的密钥即可。
内容的提问来源于stack exchange,提问作者Tan Justinn
相关产品推荐
相关产品推荐

