天天看点

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building

昨天接到领导布置的任务,与集团旗下一个子公司妙健康做接口开发,他们的接口是https的,因此我采用HttpsURLConnection来建立https网站发起的请求连接,测试demo代码如下:

package com.pcmall;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;


import javax.net.ssl.*;




public class TrustSSL {
    public static void main(String[] args) throws Exception {
    	URL console = new URL("https://xxx.xxx.xxx/xxx/xxx/xxx");
        HttpURLConnection conn = (HttpURLConnection) console.openConnection();
        conn.connect();
        System.out.println(conn.getResponseCode());
    }
}
           

报如下错误:

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

网上百度了一下,说是HTTPS证书过时导致的,我们在这里写一个假的安全验证,则成功解决该问题,解决成功后代码如下:

package com.pcmall;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;


import javax.net.ssl.*;




public class TrustSSL {
    private static class TrustAnyTrustManager implements X509TrustManager {
    
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    }
    
    private static class TrustAnyHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }


    public static void main(String[] args) throws Exception {
    	URL console = new URL("https://xxx.xxx.xxx/xxx/xxx/xxx");
        HttpURLConnection conn = (HttpURLConnection) console.openConnection();
        if (conn instanceof HttpsURLConnection)  {
        	SSLContext sc = SSLContext.getInstance("SSL");
        	sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
        	((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory());
        	((HttpsURLConnection) conn).setHostnameVerifier(new TrustAnyHostnameVerifier());
        }
        conn.connect();
        System.out.println(conn.getResponseCode());
    }
}
           

这个方法问了一圈同事,居然没人知道,我很是无语。