在本地windows環境Java服務器?訪問https服務器沒有問題,換到測試環境linux服務器訪問時出現上面這個問題,
是證書出問題了,服務器不信任我們自己創建的證書,所以在代碼中必須要忽略證書信任問題。只要在創建connection之前調用兩個方法:?
? ? ? ? trustAllHttpsCertificates();??
? ? ? ?HttpsURLConnection.setDefaultHostnameVerifier(hv);
兩個方法的具體實現,如下:
HostnameVerifier?hv?=?new?HostnameVerifier()?{??????????public?boolean?verify(String?urlHostName,?SSLSession?session)?{??????????????System.out.println("Warning:?URL?Host:?"?+?urlHostName?+?"?vs.?"?????????????????????????????????+?session.getPeerHost());??????????????return?true;??????????}??????};????????????private?static?void?trustAllHttpsCertificates()?throws?Exception?{??? ? ? ? //創建信任管理器來信任所有的證書????????javax.net.ssl.TrustManager[]?trustAllCerts?=?new?javax.net.ssl.TrustManager[1];??????????javax.net.ssl.TrustManager?tm?=?new?miTM();??????????trustAllCerts[0]?=?tm;??? ? ? ? //實例化SSL協議????????javax.net.ssl.SSLContext?sc?=?javax.net.ssl.SSLContext??????????????????.getInstance("SSL");??? ? ? ? //實例化SSl協議?信任所有證書????????sc.init(null,?trustAllCerts,?null);??????????javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc??????????????????.getSocketFactory());??????}????????static?class?miTM?implements?javax.net.ssl.TrustManager,??????????????javax.net.ssl.X509TrustManager?{??????????public?java.security.cert.X509Certificate[]?getAcceptedIssuers()?{??????????????return?null;??????????}????????????public?boolean?isServerTrusted(??????????????????java.security.cert.X509Certificate[]?certs)?{??????????????return?true;??????????}????????????public?boolean?isClientTrusted(??????????????????java.security.cert.X509Certificate[]?certs)?{??????????????return?true;??????????}????????????public?void?checkServerTrusted(??????????????????java.security.cert.X509Certificate[]?certs,?String?authType)??????????????????throws?java.security.cert.CertificateException?{??????????????return;??????????}????????????public?void?checkClientTrusted(??????????????????java.security.cert.X509Certificate[]?certs,?String?authType)??????????????????throws?java.security.cert.CertificateException?{??????????????return;??????????}??????}?
以上的解決辦法來自http://mengyang.iteye.com/blog/575671,在這里記錄一下這個問題。
這里簡單介紹下HostnameVerifier,這個接口主要是javax.net.ssl用于主機名驗證的基接口。
其中verify()這個方法驗證主機名和服務器驗證方案,這里重寫了這個方法在連接期間,如果URL的主機名和服務器名不匹配則驗證機制可以回調此借口的實現程序來確定是否應該允許此鏈接。
TrustManager從Java API那看是
就是信任管理器負責管理在進行信任決策時使用的信任材料,以及決定是否應該接受對等方提供的憑據。通過使用TrustManagerFactory或通過實現TrustManager子類之一來創建信任管理器。
SSLContext類:
這個類的實例 代表socket協議實現,它作為socket工廠或SSLEngress的工廠。這個類用一組可選的密鑰和信任管理器和安全隨機字節的源進行初始化。Java平臺的每一個實現都需要支持以下標準SSLVIEW協議。
HostnameVerifier接口:
在握手期間,如果URL的主機名和服務器的標識主機名不匹配,驗證機制可以調用該接口的實現者來確定是否應該允許該連接。
這個策略可以是基于證書的,或者可以依賴于其他認證方案。當URL主機名驗證的默認規則失敗時,將使用這個回調。
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的在linux下tomcat报javax.net.ssl.SSLHandshakeException sun.security.validator.ValidatorException: PKIX的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。