April 4, 2015

javax.net.ssl.SSLKeyException: failed hostname verification

Problem:
When my adf web application executing a web service call, I got the below error which was failed to verify the hostname.

javax.xml.ws.WebServiceException: javax.net.ssl.SSLKeyException: [Security:090504]Certificate chain received from XXXXXXXXXXXX.demos.com - YY.YY.YY.YY failed hostname verification check. Certificate contained *.demos.com but check expected XXXXXXXXXXXX.demos.com


where XXXXXXXXXXXX.demos.com is my host name.

Solution:

To avoid this error, we have two solutions. One is to make weblogic ignore the host name verification and another one is to ignore verification through code. We can use either of these solutions to avoid the above error.

The first way is the weblogic should ignore the host name verification. To do this, follow the below procedure.

  • Login to weblogic console
  • Go to Servers, then click on the server name (in my case the name is DefaultServer)
  • Go to SSL tab
  • Under the Advanced section, you can see the property "Hostname Verification"
  • By default, it value is "BEA Hostname Verifier". Change this value to "None"
  • Click on Save and restart the server
  • Run again the application now

And the Second way is to write a code snippet to ignore verification of host name. Below is the java code to do so.
     
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) {
                }
            } };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                System.out.println("HostnameVerifier - "+hostname+" Session: "+session);
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);


Note: These two ways are only for testing purpose, may not suggestible to use in production environment.