Friday, May 25, 2012

Avoiding the "javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed" error



        The SSLHandshakeException is thrown by java when the host you are trying to contact doesn't have a valid SSL certificate for that hostname.
        I want connect to host which certificate details is "This CA Root certificate is not trusted because it is not in the Trusted Root Certification Authorities store.". So When I connected this site with java URLConnection it gives exception "javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed" . Then I have searched and find solution as following:



package com.blogspot.vmustafayev4en.ca;

import java.io.*;
import java.net.*;
import javax.net.ssl.*;

public class TestHttps {
    public static void main(String args[]) throws Exception {


        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                }
        };
  // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            System.out.println("Error" + e);
        }
  // Now you can access an https URL without having the certificate in the truststore
        try {


            HostnameVerifier hv = new HostnameVerifier() {
                public boolean verify(String urlHostName, SSLSession session) {
                    System.out.println("Warning: URL Host: " + urlHostName + " vs. "
                            + session.getPeerHost());
                    return true;
                }
            };

            String datam = "param=myparam";
            URL url = new URL("https://myurlgoeshere/blabla.aspx");
            URLConnection conn = url.openConnection();
            HttpsURLConnection urlConn = (HttpsURLConnection) conn;
            urlConn.setHostnameVerifier(hv);
            conn.setDoOutput(true);
            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
            wr.write(datam);
            wr.flush();

            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

            StringBuilder sb = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                sb.append(inputLine);
            }
            in.close();
            String res = sb.toString();
            System.out.println(res);

        } catch (MalformedURLException e) {
            System.out.println("Error in SLL Connetion" + e);
        }


    }
}



urlConn.setHostnameVerifier(hv); 
That is all u need to prevent that exception. We use VPN connection so don't need Certificate :)

8 comments: