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

升级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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:50:21