Spring Security JWT验证报错:RS256与HS256签名密钥不匹配问题
问题解决:JWT校验时UnsupportedJwtException错误
错误根源
你生成JWT用的是HS256(HMAC-SHA256)对称加密算法,但校验逻辑却在尝试用RS256(RSA-SHA256)的规则验证,算法与密钥类型不匹配,导致抛出异常。
解决方案
方案1:修正校验逻辑,匹配HS256生成规则
如果不需要切换算法,直接让校验逻辑和生成逻辑保持一致即可:
- 确保校验代码使用和生成时相同的密钥与算法,示例校验代码如下:
public Claims extractAllClaims(String token) { return Jwts.parserBuilder() .setSigningKey(getSignKey()) // 复用生成token时的getSignKey方法 .build() .parseClaimsJws(token) .getBody(); } // 复用生成类中的密钥生成方法 private Key getSignKey() { byte[] keyBytes= Decoders.BASE64.decode(SECRET); return Keys.hmacShaKeyFor(keyBytes); }
- 检查校验代码中是否存在强制指定RS256算法的逻辑,如有则删除或改为HS256。
方案2:切换为RS256非对称加密(如果业务需要)
如果确实需要使用RS256,需修改生成代码为RSA密钥对签名:
生成token的代码修改:
// 加载RSA私钥(建议从配置文件或密钥管理系统读取,硬编码仅作示例) private PrivateKey getRsaPrivateKey() throws Exception { String privateKeyPem = "-----BEGIN PRIVATE KEY-----\n" + "你的RSA私钥内容\n" + "-----END PRIVATE KEY-----"; return Keys.privateKeyFor(privateKeyPem.getBytes(StandardCharsets.UTF_8)); } private String createToken(Map<String, Object> claims, String userName) throws Exception { return Jwts.builder() .setClaims(claims) .setSubject(userName) .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 30)) .signWith(getRsaPrivateKey(), SignatureAlgorithm.RS256) // 使用RS256和私钥签名 .compact(); }
校验token的代码:
// 加载对应RSA公钥 private PublicKey getRsaPublicKey() throws Exception { String publicKeyPem = "-----BEGIN PUBLIC KEY-----\n" + "对应RSA公钥内容\n" + "-----END PUBLIC KEY-----"; return Keys.publicKeyFor(publicKeyPem.getBytes(StandardCharsets.UTF_8)); } public Claims extractAllClaims(String token) throws Exception { return Jwts.parserBuilder() .setSigningKey(getRsaPublicKey()) .build() .parseClaimsJws(token) .getBody(); }
关键注意点
- 生成与校验必须使用相同的签名算法:HS256用对称密钥,RS256用RSA密钥对,绝对不能混用
- 确保密钥一致性:HS256生成和校验用同一个Base64解码后的密钥;RS256用私钥签名,公钥校验
内容的提问来源于stack exchange,提问作者Ciube
相关产品推荐
相关产品推荐

