javax.net.ssl.SSLHandshakeException: No negotiable cipher suite 问题解决

错误

javax.net.ssl.SSLHandshakeException: No negotiable cipher suite
	at sun.security.ssl.ClientHello$ClientHelloKickstartProducer.produce(ClientHello.java:541)
	at sun.security.ssl.SSLHandshake.kickstart(SSLHandshake.java:509)
	at sun.security.ssl.ClientHandshakeContext.kickstart(ClientHandshakeContext.java:110)
	at sun.security.ssl.TransportContext.kickstart(TransportContext.java:234)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:393)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:372)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:587)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:167)

情形

如果你的项目符合以下条件并抛错,那么这个解决方案适合你

  1. 项目启动用到了jar依赖分离模式,即启动时指定-Djava.ext.dirs参数
  2. 项目用到了org.apache.http.impl.client包中的内容,即发送网络请求
  3. 请求的网络地址为https协议

原因

-Djava.ext.dirs是通过设置系统属性的方式也加载jar包的,他会会覆盖Java本身的ext设置,如果您的程序没有指定该系统属性(-Djava.ext.dirs=xxx)那么该加载器默认加载%JAVA_HOME%/jre/lib/ext目录下的所有jar文件。但如果你手动指定系统属性且忘了把%JAVA_HOME%/jre/lib/ext路径给加上,那么程序不会去加载%JAVA_HOME%/lib/ext下面的jar文件,这意味着你将失去一些功能,例如java自带的加解密算法实现。到这里,您应该明白了为什么会抛错,因为https协议涉及到SSL证书的加解密,而不加载java自带的ext目录无法实现,所以会抛错

解决

知道原因后,解决就简单了,方案有两个(推荐第二个):

  1. 将所有程序依赖的jar拷贝到%JAVA_HOME%/jre/lib/ext中,启动程序时不指定-Djava.ext.dirs参数,此方案不推荐,这样jdk就只能为一个程序服务,丢失了隔离性,可能会导致一台服务器上的其它程序无法使用
  2. -Djava.ext.dirs属性配置多个目录,实例: java -jar -Djava.ext.dirs=目录1:目录2…,例如:java -jar -Djava.ext.dirs=./lib:/usr/lib/jdk1.8.0/jre/lib/ext xxx.jar
引用:HTTP Status 500 - javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find ... 引用:Java Spring应用发送数据报如下问题javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 原因分析: 引用:用httpclient访问https资源时,会出现异常,与环境也有关系,有些机器请求正常。 解决方案: 在HTTPS通信中,当Java程序尝试与服务端建立安全连接时,会进行SSL握手过程。如果在握手过程中出现异常javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException,可能是由于证书验证失败导致的。这种异常通常有两种原因:一是服务端证书不被信任,二是客户端无法找到合适的证书链。 解决这个问题的方法有以下几种: 1. 信任自签名证书:可以通过自定义TrustManager来信任自签名的证书。但这种方法存在安全风险,因为所有的自签名证书都会被信任。 2. 导入服务端证书:可以将服务端的证书导入到Java的信任证书库中,以确保它被信任。可以使用keytool工具将证书导入到Java信任库中。 3. 禁用证书验证:在开发环境中,可以禁用证书验证来避免这个问题。但在生产环境中不建议这样做,因为会降低通信的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值