Ignoring the Host Name verification while invoking the HTTPS service through HttpsURLConnection
Sometimes you may receive the Host Name mismatch exception while invoking the HTTPS service from the Java client even though the valid certificate is installed to the key store.javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching <Host Name> found
The root cause of the exception is the CN name of the certificate is not matching with the host name used to connect the service.
In real scenario while the certificate is signed with third party certificate authority , the CN name will be specified as the host name of the server where the service is hosted or wildcard name will be specified e.g *.example.com to represent all sub domains in a domain. So there will not be any issue while connecting to the service.
This mismatch exception will happen most of the time communicating with self signed certificate, the certificate is signed with CN name that is not matching with the host name.
How to Fix the issue
To resolve the issue, the certificate should be signed with proper CN name or we can create a custom host name verifier to customize the host name verification functionality.We have to return true from the custom host name verifier for the host name for which the CN name is mismatching.This will connect to the service irrespective of the host name used .
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.HttpURLConnection;
public class HTTPCaller {
static {
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){
public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("localhost")) {
return true;
}
return false;
}
});
}
public static String execute() {
String targetURL="https://localhost/test"
URL url;
HttpURLConnection connection = null;
try {
url = new URL(targetURL);
url = new URL(url.toString());
connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("accept", "application/xml"); //for GET service to return xml payload
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
System.out.println("\n Received response" + System.currentTimeMillis());
String line;
StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return (e.getClass().getName()+":"+e.getMessage().toString());
}
finally {
if (connection != null) {
connection.disconnect();
}
}
}