【java】mac下出现 java.lang.SecurityException: JCE cannot authenticate the provider BC

本文详细解析了在使用BouncyCastle库时遇到的加密错误问题,包括java.lang.SecurityException和JCE无法验证provider BC的异常。通过在指定目录放置bcprov库文件,成功解决了运行时的错误。

运行报错:

org.bouncycastle.openssl.PEMException: problem parsing ENCRYPTED PRIVATE KEY: java.lang.SecurityException: JCE cannot authenticate the provider BC
	at org.bouncycastle.openssl.PEMReader$EncryptedPrivateKeyParser.parseObject(Unknown Source)
	at org.bouncycastle.openssl.PEMReader.readObject(Unknown Source)
	at org.whispersystems.textsecuregcm.push.RetryingApnsClient.initializePrivateKey(RetryingApnsClient.java:135)
	at org.whispersystems.textsecuregcm.push.RetryingApnsClient.<init>(RetryingApnsClient.java:65)
	at org.whispersystems.textsecuregcm.push.APNSender.<init>(APNSender.java:61)
	at org.whispersystems.textsecuregcm.WhisperServerService.run(WhisperServerService.java:182)
	at org.whispersystems.textsecuregcm.WhisperServerService.run(WhisperServerService.java:111)
	at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:43)
	at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:87)
	at io.dropwizard.cli.Cli.run(Cli.java:78)
	at io.dropwizard.Application.run(Application.java:93)
	at org.whispersystems.textsecuregcm.WhisperServerService.main(WhisperServerService.java:283)
Caused by: java.lang.SecurityException: JCE cannot authenticate the provider BC
	at javax.crypto.Cipher.getInstance(Cipher.java:656)
	at javax.crypto.Cipher.getInstance(Cipher.java:595)
	... 12 more
Caused by: java.util.jar.JarException: file:/opt/code/signal-Server-master/target/TextSecureServer-1.87.jar has unsigned entries - org/whispersystems/dispatch/DispatchManager$4.class
	at javax.crypto.JarVerifier.verifySingleJar(JarVerifier.java:502)
	at javax.crypto.JarVerifier.verifyJars(JarVerifier.java:363)
	at javax.crypto.JarVerifier.verify(JarVerifier.java:289)
	at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:164)
	at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:190)
	at javax.crypto.Cipher.getInstance(Cipher.java:652)
	... 13 more

解决:

在目录/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext下放bcprov的两个库:

https://download.youkuaiyun.com/download/idwtwt/10768832

 

参考:

https://blog.youkuaiyun.com/wangxi_xixi/article/details/78027795

https://stackoverflow.com/questions/8409069/where-is-the-jre-lib-security-directory-on-mac-os-x

Java加密扩展(JCE)中,出现 `java.lang.SecurityException: JCE cannot authenticate the provider BC` 错误通常与Bouncy Castle(BC)加密提供者的验证失败有关。该问题可能出现在JDK版本升级、JAR包签名验证失败或配置不当的情况下。 ### 原因分析 该异常通常由以下几种原因引起: 1. **JDK版本与Bouncy Castle版本不兼容** 如果使用的是较旧的JDK版本(如JDK 7),而引入的Bouncy Castle JAR包是为更高版本的JDK(如JDK 8)构建的,会导致类加载失败或签名验证失败,从而抛出 `SecurityException` [^2]。 2. **JAR包未正确签名或被篡改** JDK在加载加密提供者时会验证JAR包的签名。如果JAR文件被修改或签名无效,JDK将拒绝加载该提供者,并抛出此异常 [^1]。 3. **Bouncy Castle未正确注册为安全提供者** Bouncy Castle需要在JVM中注册为一个安全提供者,否则无法正常使用。如果未正确配置 `java.security` 文件或未在代码中动态添加提供者,也会导致此异常 [^3]。 --- ### 解决方案 #### 1. 确保JDK版本与Bouncy Castle版本兼容 - 如果使用JDK 7,应使用Bouncy Castle 1.58或更早版本(如 `bcprov-jdk15on-1.58.jar`)。 - 如果使用JDK 8及以上版本,可使用Bouncy Castle 1.62及以上版本。 - 避免使用为JDK 8及以上构建的Bouncy Castle JAR包在JDK 7环境中运行 [^2]。 #### 2. 检查JAR包完整性与签名 - 确保使用的 `bcprov-jdk15on-*.jar` 文件未被修改。 - 使用命令检查JAR签名: ```bash jarsigner -verify -verbose -certs bcprov-jdk15on-162.jar ``` 如果输出中显示“jar verified.”,则表示签名有效 [^1]。 #### 3. 正确注册Bouncy Castle为安全提供者 **方法一:在代码中动态注册** ```java import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.Security; public class BcSetup { static { Security.addProvider(new BouncyCastleProvider()); } } ``` **方法二:修改 `java.security` 文件** 在JDK安装目录下的 `jre/lib/security/java.security` 文件中添加以下行: ``` security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider ``` 其中 `9` 表示优先级,可根据现有提供者顺序进行调整 [^3]。 #### 4. 使用兼容的JAR包 如果问题仍然存在,尝试使用 `bcprov-jdk15-145.jar` 或其他已知兼容的版本。此版本适用于JDK 7环境 [^4]。 --- ### 验证方式 在代码中打印当前注册的安全提供者列表,以确认Bouncy Castle是否已正确加载: ```java import java.security.Provider; import java.security.Security; public class ProviderCheck { public static void main(String[] args) { Provider[] providers = Security.getProviders(); for (Provider provider : providers) { System.out.println(provider.getName()); } } } ``` 若输出中包含 `BC`,则表示Bouncy Castle已成功注册。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值