2019年2月23日 星期六

解決 Java Https Request 普遍的 PKIX path building failed 問題


導致產生 PKIX path building failed 這樣的例外,原因是開發環境/生產環境中的 Java 使用 HTTPS 時會使用 Java Home 目錄下的 SSL 憑證,這個預設憑證並沒有經過 CA 認證,因此不被 CA 認可過的證書不會被 Java 做 Https Request 時接受,另一個原因是 Java 存放 SSL 憑證的目錄並沒有可用的 SSL 憑證 (可以自己簽)。

本文所摘錄之解決方案是自行設計證書認證管理物件,將其中的證書檢驗方法覆寫且不做任何驗證,簡單的說就是跳過證書驗證,所以不適合在生產環境使用,若有中間人攻擊,則無法在程式中做防禦 。

程式碼:


private static String getURL(String https_url) throws NoSuchAlgorithmException, KeyManagementException{
        
        //建立 CA 認證管理物件
        TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    //跳過驗證
                }
                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    //跳過驗證
                }

            }
        };
        
        SSLContext sslc = SSLContext.getInstance("TLS");
        sslc.init(null, trustAllCerts, null);
        LayeredConnectionSocketFactory lcsf = new SSLConnectionSocketFactory(sslc);
        CloseableHttpClient clientObject = HttpClients.custom()
                .setSSLSocketFactory(sslSocketFactory)
                .build();
        
        try {
            
            HttpGet request = new HttpGet(https_url);
            request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) ...");

            CloseableHttpResponse response = clientObject.execute(request);
            
                    
            BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
  
           String body = "";
    String input; 
    while ((input = br.readLine()) != null){
              body += input;
    }
    br.close();
           
           return body;

        } catch (MalformedURLException e) {
               e.printStackTrace();
        } catch (IOException e) {
               e.printStackTrace();
        }
        return "";
   }



Reference:
https://confluence.atlassian.com/kb/unable-to-connect-to-ssl-services-due-to-pkix-path-building-failed-779355358.html
https://stackoverflow.com/questions/21076179/pkix-path-building-failed-and-unable-to-find-valid-certification-path-to-requ
https://www.mkyong.com/java/java-https-client-httpsurlconnection-example/
https://www.aneasystone.com/archives/2016/04/java-and-https.html

沒有留言:

張貼留言

© Mac Taylor, 歡迎自由轉貼。
Background Email Pattern by Toby Elliott
Since 2014