Linux 环境下 java17使用hutool国密4加解密出现 SecurityException: JCE cannot authenticate the provider BC

一。 问题来源

最近使用了hutool工具包里的 国密4工具类来实现加解密。本地环境正常,但部署到测试环境 linux下的k8s集群中 就会出现解密报错问题
完整的报错日志如下

Caused by: cn.hutool.crypto.CryptoException: SecurityException: JCE cannot authenticate the provider BC
at cn.hutool.crypto.SecureUtil.createCipher(SecureUtil.java:1034)
at cn.hutool.crypto.CipherWrapper.<init>(CipherWrapper.java:39)
at cn.hutool.crypto.symmetric.SymmetricCrypto.init(SymmetricCrypto.java:150)
at cn.hutool.crypto.symmetric.SymmetricCrypto.<init>(SymmetricCrypto.java:127)
at cn.hutool.crypto.symmetric.SM4.<init>(SM4.java:171)
at cn.hutool.crypto.symmetric.SM4.<init>(SM4.java:146)
at cn.hutool.crypto.symmetric.SM4.<init>(SM4.java:78)
at com.style.common.config.encryptor.Sm4Encryptor.<clinit>(Sm4Encryptor.java:60)
... 31 common frames omitted
Caused by: java.lang.SecurityException: JCE cannot authenticate the provider BC
at java.base/javax.crypto.Cipher.getInstance(Cipher.java:722)
at cn.hutool.crypto.SecureUtil.createCipher(SecureUtil.java:1032)
... 38 common frames omitted
Caused by: java.lang.IllegalStateException: zip file closed
at java.base/java.util.zip.ZipFile.ensureOpen(ZipFile.java:831)
at java.base/java.util.zip.ZipFile.getManifestName(ZipFile.java:1057)
at java.base/java.util.zip.ZipFile$1.getManifestName(ZipFile.java:1100)
at java.base/javax.crypto.JarVerifier.verifySingleJar(JarVerifier.java:461)
at java.base/javax.crypto.JarVerifier.verifyJars(JarVerifier.java:317)
at java.base/javax.crypto.JarVerifier.verify(JarVerifier.java:260)
at java.base/javax.crypto.ProviderVerifier.verify(ProviderVerifier.java:130)
at java.base/javax.crypto.JceSecurity.verifyProvider(JceSecurity.java:190)
at java.base/javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:218)
at java.base/javax.crypto.Cipher.getInstance(Cipher.java:718)
... 39 common frames omitted

二。问题分析

SecurityException: JCE cannot authenticate the provider BC: 这个错误与Bouncy Castle(BC)加密提供程序的验证有关。这可能是因为Bouncy Castle库的某些问题,或者JCE(Java Cryptography Extension)无法验证Bouncy Castle作为提供程序。
我们遇到的这个错误应该时第二个 无法验证Bouncy Castle作为提供程序。

三。解决办法

那这个解决办法无非两个

  • 第一个 解决无法验证Bouncy Castle作为提供程序的问题。
  • 第二个 找一个不验证的Bouncy Castle作为提供程序的jdk

很明显 第二种方式简单粗暴 但是不是所有的环境都满足条件 直接升级
目前我们也是用的这种方式解决
替换 oracle-jdk17 为 open-jdk17

当然第一种方式也是可以解决的 只是步骤有点稍微繁琐,而且不一定能解决 也会被Bouncy Castle版本影响

jdk1.8的 解决步骤如下
1、找到jdk安装的根路径 打开jre/lib

2、下载bcprov 对应版本的jar 例如 需要某个加密依赖 org.bouncycastle:bcprov-jdk15on:jar:1.70 1.7的版本 那我就下载1.7版本

复制下载的jar 到 /jdk的根路径/jre/lib/ext 如果这个ext 目录不存在的话 需要新建 (应该都会存在)

3、在/etc/profile文件下CLASSPATH添加jre相关目录

export CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/jre/lib/ext

4、在{jdk根目录}/jre/lib/security

例如 /usr/local/develop/java/jdk1.8.0_181/jre/lib/security

打开java.security 这个文件

先找到 security.provider 对应的文件配置

添加如下配置

security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider

security.provider.11 这个根据上面的排序来,我的本机排序是到了11,所以我这里加了11。
保存该配置后,在进行测试。

jdk17的配置方法大同小异 (需要自行测试下)
唯一不一样的 根目录下没有jre
我们需要使用命令 生成jre目录
在jdk17的根目录下执行

#mac / linux
/bin/jlink --module-path jmods --add-modules java.desktop --output jre
#win
\bin\jlink --module-path jmods --add-modules java.desktop --output jre
  1. 然后进入到 jdk根路径/jre/lib
  2. 新建 ext目录
  3. 然后复制下的 jar到这里
  4. 打开安全配置 这个和之前路径不太一样
    /jdk根目录/conf/security
  5. 和之前方式一样 找到security.provider 对应的配置

    添加如下配置
security.provider.14=org.bouncycastle.jce.provider.BouncyCastleProvider

security.provider.14 这个根据上面的排序来,我的本机排序是到了14,所以我这里加了14。
保存该配置后,在进行测试。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2023年11月7日
下一篇 2023年11月7日

相关推荐