java.security.ProviderException: java.security.KeyException

本文解决了一个在CentOS 6.5环境中使用OpenJDK 8发起HTTPS请求到微信API时出现的SSL异常问题。异常源于OpenJDK依赖的libsunec.so与libnss不兼容。解决方案包括更新libnss组件并重启服务器。

问题:

在centos6.5上使用openjdk8 用https请求微信api

javax.net.ssl.SSLException: java.security.ProviderException: java.security.KeyException
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1906)
    at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1889)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1410)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:553)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:412)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:179)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:328)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:612)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:447)
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:884)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
    ....
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.security.ProviderException: java.security.KeyException
    at sun.security.ec.ECKeyPairGenerator.generateKeyPair(ECKeyPairGenerator.java:147)
    at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:703)
    at sun.security.ssl.ECDHCrypt.<init>(ECDHCrypt.java:77)
    at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:721)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:281)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    ... 57 more
Caused by: java.security.KeyException
    at sun.security.ec.ECKeyPairGenerator.generateECKeyPair(Native Method)
    at sun.security.ec.ECKeyPairGenerator.generateKeyPair(ECKeyPairGenerator.java:128)
    ... 66 more

原因

dd /usr/lib/jvm/lib/amd64/libsunec.so 依赖的是libnss,所以更新libnss即可

解决:

1.更新nss

sudo yum upgrade nss

2.重启服务器

Java 安全编程中,`Security.addProvider()` 是用于向 JVM 添加加密服务提供者(如 Bouncy Castle、Kona-Crypto、Amazon Corretto Crypto Provider 等)的核心方法。通过该方法,开发者可以扩展 Java 原生安全 API 的功能,支持更多算法和更强的安全性保障。 ### 使用 `Security.addProvider()` 添加 KonaCryptoProvider 腾讯 Kona-Crypto 提供了对国密算法(如 SM2/SM3/SM4)的完整支持,并可通过 `Security.addProvider(new KonaCryptoProvider())` 显式注册到安全提供者列表中[^1]。其典型使用方式如下: ```java import com.tencent.konacrypto.KonaCryptoProvider; import java.security.Security; public class ProviderExample { static { Security.addProvider(new KonaCryptoProvider()); } public static void main(String[] args) { System.out.println("KonaCryptoProvider added."); } } ``` 上述代码将 KonaCryptoProvider 注册为系统级别的安全提供者,使得后续调用如 `KeyPairGenerator.getInstance("EC", "KonaCrypto")` 能够成功获取基于 SM2 的密钥生成器实例。 ### 使用 `Security.addProvider()` 添加 AmazonCorrettoCryptoProvider Amazon Corretto 提供的 AmazonCorrettoCryptoProvider(ACCP)是专为增强 TLS 和加密性能而设计的高性能安全提供者。它通常用于 AWS 环境下的高安全性要求场景。添加方式如下: ```java import software.amazon.cryptography.provider.AmazonCorrettoCryptoProvider; import java.security.Security; public class ACCPExample { static { Security.addProvider(new AmazonCorrettoCryptoProvider()); } public static void main(String[] args) { System.out.println("AmazonCorrettoCryptoProvider added."); } } ``` 添加后,可以通过指定 `"AmazonCorretto"` 作为提供者名称来使用其优化后的算法实现,例如: ```java KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "AmazonCorretto"); kpg.initialize(256); ``` 这种方式适用于需要与 AWS 服务集成并利用硬件加速加密能力的应用场景[^2]。 ### 上下文与注意事项 - **顺序影响优先级**:`Security.addProvider()` 添加的提供者会插入到系统提供者列表中,位置越靠前优先级越高。某些算法可能有多个实现,因此需注意添加顺序。 - **线程安全**:建议在静态初始化块中调用 `addProvider()`,以确保线程安全且仅执行一次。 - **依赖管理**:使用第三方提供者时,必须确保其 JAR 包已正确引入项目构建路径中,否则会导致 `NoClassDefFoundError` 或 `ProviderException`。 ### 示例:结合国密算法使用 以下示例展示了如何结合 KonaCryptoProvider 实现 SM2 密钥对生成: ```java import com.tencent.konacrypto.KonaCryptoProvider; import java.security.KeyPairGenerator; import java.security.Security; public class SM2KeyPairExample { static { Security.addProvider(new KonaCryptoProvider()); } public static void main(String[] args) throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "KonaCrypto"); kpg.initialize(256); System.out.println("Generated SM2 key pair: " + kpg.generateKeyPair()); } } ``` 此代码片段首先注册了 KonaCryptoProvider,随后获取 EC 类型的密钥生成器并初始化为 256 位椭圆曲线参数,从而生成符合 SM2 标准的密钥对。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值