【SSL】调用HTTPS://服务遇到错误:unable to find valid certification path to requested target
生活随笔
收集整理的这篇文章主要介绍了
【SSL】调用HTTPS://服务遇到错误:unable to find valid certification path to requested target
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
前言
- OkHttpClient
最近有个需求,需要调用一个https开头的URL服务。
服务方提供了一个demo,但,demo是调用http的服务。
网上找了一大圈,发现盖起来要这样要那样的。都不符合我的想法,试了几个也没成功。
我的想法比较简单:有没有一种方法,让我在不改动demo的前提下,让demo跑起来。
经过我仔细地回想一下,发现这个办法可行,我之前还实现过。
错误内容
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 targetat sun.security.ssl.Alerts.getSSLException(Alerts.java:192)at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959)at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514)at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379)at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337)at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209)at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)at sc.HttpClientUtil.postWithJsonMsg(HttpClientUtil.java:66)at sc.appPay.main(appPay.java:105) Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targetat sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)at sun.security.validator.Validator.validate(Validator.java:260)at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)... 26 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targetat sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)... 32 more题外话
对于调用HTTPS的服务,可以参考《java 安全性编程指南》。
解决思路
将HTTPS的证书添加到本地证书库中。在程序启动时,使用指定的证书库验证证书和CA。
相关知识:
- 当访问的URL是以https://开头的话,VM将自动地激活JSSE。
- 服务器会向客户端发送它的证书以供验证。
- 客户端会验证证书,以确认这个服务器正式他想链接并通信的那个服务器,并且确认签发证书的CA是可信任的。
- 环境变量javax.net.ssl.trustStore告知客户端的JSSE使用哪个证书库。证书库中有我们可以信任的证书和CA。
- 环境变量javax.net.ssl.trustStorePassword告知客户端的JSSE证书库的密码。
- 如果未指定证书库,则使用缺省的证书库。缺省的证书库的位置为%JRE_HOME%/lib/security/cacerts或者%JAVA_HOME%/jre/lib/security/cacerts。默认密码为changeit。
操作
在合适的位置添加下面这段静态代码:
static {File jksFile = new File("localhost.jks");System.out.println("jks file : " + jksFile.getAbsolutePath());System.setProperty("javax.net.ssl.trustStore", jksFile.getAbsolutePath());System.setProperty("javax.net.ssl.trustStorePassword", "changeit");}对应的项目结构为:
项目目录 ├─src │ ├─main │ │ ├─java │ │ │ └─sc │ │ └─resources │ └─test │ ├─java │ └─resources └─localhost.jks其它
总结
以上是生活随笔为你收集整理的【SSL】调用HTTPS://服务遇到错误:unable to find valid certification path to requested target的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Spring @Value 设置默认值
- 下一篇: jd-gui