Jose4j 0.9.4及以下版本在FIPS启用主机调用toJson抛ClassCastException
Jose4j 0.9.4及更低版本在FIPS启用环境下调用toJson抛出ClassCastException的解决方案
问题现象
在CentOS Stream 8主机上通过fips-mode-setup --enable启用FIPS模式后,运行以下代码时,jose4j版本≤0.9.4会在toJson方法抛出ClassCastException;禁用FIPS模式则无异常。
测试代码:
RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048); rsaJsonWebKey.setAlgorithm("RS256"); rsaJsonWebKey.setKeyId("authServer"); rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
问题根源
异常触发点在org.jose4j.jwk.RsaJsonWebKey.getRsaPrivateKey(RsaJsonWebKey.java:124)的强转逻辑:
return (RSAPrivateKey) privateKey;
- FIPS启用时,生成的私钥实际类型为
sun.security.pkcs11.P11Key$P11PrivateKey(SunPKCS11-NSS-FIPS RSA私钥),该类未直接实现RSAPrivateKey接口,强制类型转换失败; - FIPS禁用时,私钥类型为
sun.security.rsa.RSAPrivateCrtKeyImpl(SunRsaSign RSA私钥CRT密钥),该类实现了RSAPrivateKey接口,强转正常。
解决方案
优先升级jose4j版本
升级至0.9.5及以上版本,官方已修复该兼容性问题,修改了私钥类型的处理逻辑,不再依赖直接强制类型转换,改用更通用的方式获取RSA私钥参数。临时兼容方案(无法升级时)
若因依赖限制无法升级版本,可手动将PKCS11私钥转换为标准RSAPrivateKey实现:
// 获取当前私钥 PrivateKey originalPrivateKey = rsaJsonWebKey.getPrivateKey(); // 通过KeyFactory转换为标准RSA私钥 KeyFactory keyFactory = KeyFactory.getInstance("RSA"); RSAPrivateKeySpec privateKeySpec = keyFactory.getKeySpec(originalPrivateKey, RSAPrivateKeySpec.class); RSAPrivateKey standardRsaPrivateKey = keyFactory.generatePrivate(privateKeySpec); // 设置转换后的私钥到RsaJsonWebKey rsaJsonWebKey.setPrivateKey(standardRsaPrivateKey); // 再调用toJson方法 rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
注意:此方案要求私钥标记为可提取,FIPS模式下若私钥被配置为不可提取则无法使用。
内容的提问来源于stack exchange,提问作者Dmil Team
相关产品推荐
相关产品推荐

