升级jjwt至0.12.3后使用PKCS12密钥库验证JWT报错
JJWT 0.12.3升级后PKCS12密钥签名验证报错解决
问题原因
JJWT从0.9.1升级到0.12.3后,对密钥类型的校验变得更严格:
- RS256属于非对称签名算法,签名必须使用PrivateKey,验证必须使用PublicKey。
- 你原代码中
getKey()方法返回的是私钥,验证时传入私钥不符合要求,触发错误提示:JWS verification key must be either a SecretKey (for MAC algorithms) or a PublicKey (for Signature algorithms)。 - 同时0.12.x版本的API有变更,旧的部分方法已过时,需要适配新的调用方式。
修正方案
1. 拆分密钥获取方法
分别实现私钥(签名用)和公钥(验证用)的获取逻辑:
// 获取用于签名的私钥 private static PrivateKey getPrivateKey() throws Exception { KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore.load(GenerateValidateKey.class.getResourceAsStream("/test.p12"), "test".toCharArray()); Enumeration<String> aliases = keystore.aliases(); String keyAlias = ""; while (aliases.hasMoreElements()) { keyAlias = aliases.nextElement(); } return (PrivateKey) keystore.getKey(keyAlias, "test".toCharArray()); } // 获取用于验证的公钥 private static PublicKey getPublicKey() throws Exception { KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore.load(GenerateValidateKey.class.getResourceAsStream("/test.p12"), "test".toCharArray()); Enumeration<String> aliases = keystore.aliases(); String keyAlias = ""; while (aliases.hasMoreElements()) { keyAlias = aliases.nextElement(); } return keystore.getCertificate(keyAlias).getPublicKey(); }
2. 适配签名代码
使用私钥进行签名,同时遵循0.12.3的API规范:
Map<String, Object> claims = new HashMap<>(); claims.put("aud", "test"); claims.put("sub", "test"); LocalDateTime now = LocalDateTime.now(); LocalDateTime expiration = now.plusHours(1); // 可自行调整过期时间 String token = Jwts.builder() .setClaims(claims) .setSubject("test") .setIssuedAt(Date.from(now.atZone(ZoneId.systemDefault()).toInstant())) .setExpiration(Date.from(expiration.atZone(ZoneId.systemDefault()).toInstant())) .signWith(getPrivateKey(), SignatureAlgorithm.RS256) .compact();
3. 适配验证代码
使用公钥进行JWT验证,同时使用新版的解析器构建方式:
Claims verifiedClaims = Jwts.parserBuilder() .setSigningKey(getPublicKey()) .requireAudience("test") .build() .parseClaimsJws(token) .getBody();
额外说明
- 0.12.x版本中
Jwts.parser()已被标记为过时,推荐使用Jwts.parserBuilder()构建解析器,这也是更符合新版API设计的用法。 - 非对称算法严格区分私钥和公钥是安全规范要求,0.9.1版本的宽松校验存在安全隐患,新版JJWT的限制是合理的安全增强。
内容的提问来源于stack exchange,提问作者b3lowster
相关产品推荐
相关产品推荐

