【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