使用nimbusds生成JWS报PS256算法不支持错误如何解决
错误产生原因
- 核心原因是Java 8原生自带的JCE加密组件没有内置PS256(即RSASSA-PSS with SHA-256)签名算法的实现。PS256/PS384/PS512系列签名算法是JDK 11之后才默认纳入标准实现的,nimbus库虽然在代码层声明支持PS系列算法,但实际运行时依赖底层JCE提供的算法实现,缺失对应实现时就会抛出你看到的不支持算法错误。
- 你的代码中存在一处会导致后续验签失败的逻辑错误:从私钥对象推导公钥时,错误使用私钥指数作为公钥指数生成RSA公钥。RSA密钥对中公钥指数是公开值(通常为65537),私钥指数是需要保密的核心参数,你当前写法生成的公钥是完全无效的。
修复方案
- 引入BouncyCastle安全加密组件,补全Java 8缺失的算法支持
- 先引入适配Java 8的BouncyCastle依赖,Maven坐标如下:
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency> - 在加密逻辑执行前(可以放在类静态块、项目启动类中,全局执行一次即可)注册BouncyCastle为安全提供方:
import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.Security; static { Security.addProvider(new BouncyCastleProvider()); }
- 先引入适配Java 8的BouncyCastle依赖,Maven坐标如下:
- 修正公钥推导的错误逻辑
替换原有错误的公钥生成代码,从PKCS8私钥中提取正确的公钥参数:// 删除原有错误的公钥生成逻辑 // RSAPrivateKeySpec privKeySpec = kf.getKeySpec(privateKey, RSAPrivateKeySpec.class); // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(privKeySpec.getModulus(), privKeySpec.getPrivateExponent()); // 替换为正确逻辑:PKCS8格式的RSA私钥本身携带公钥指数参数 RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey; RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( rsaPrivateKey.getModulus(), rsaPrivateKey.getPublicExponent() ); RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(pubKeySpec); - 可选优化:修正日志打印的小问题,你打印tp证书对应JWK的日志语句缺少占位符,无法正常输出JWK内容,调整为:
log.info("jwk from tp certi : {}", jwk);
完成以上调整后,PS256签名即可正常执行,且生成的签名可以被正常验签。
内容的提问来源于stack exchange,提问作者Prakhar
相关产品推荐
相关产品推荐

