SSL handshake alert: unrecognized_name Exception

apache

This tutorial explains how to handle SSL handshake alert: unrecognized_name exception while calling an URL over SSL/https .

When I tried to connect a web-server over SSL, I was getting the below error continuously. This happened with JDK1.7 and above.

Below is the sample Java programme which I was running.

Issue :

private static String makeSSLCall(final String URL) throws Exception {
	try {
    		SSLContext sslContext = SSLContext.getInstance("SSL");

    		// set up a TrustManager that trusts everything
    		sslContext.init(null, new TrustManager[] { new X509TrustManager() {
    			public X509Certificate[] getAcceptedIssuers() {
    				System.out.println("getAcceptedIssuers =============");
    				return null;
    			}

    			public void checkClientTrusted(X509Certificate[] certs,
    					String authType) {
    				System.out.println("checkClientTrusted =============");
    			}

    			public void checkServerTrusted(X509Certificate[] certs,
    					String authType) {
    				System.out.println("checkServerTrusted =============");
    			}
    		} }, new SecureRandom());

    		HttpsURLConnection.setDefaultSSLSocketFactory(
    				sslContext.getSocketFactory());

    		HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
			public boolean verify(String arg0, SSLSession arg1) {
				System.out.println("hostnameVerifier =============");
				return true;
			}
		});

    		URL url = new URL(URL);
    		URLConnection conn = url.openConnection();
            	BufferedReader reader = 
                new BufferedReader(new InputStreamReader(conn.getInputStream()));
            	String line;
            	while ((line = reader.readLine()) != null) {
                	System.out.println("responseCode-->"+line+" for mailerURL : "+URL);
            	}
    	} catch (Exception e) {
    		e.printStackTrace();
    	} 
}
public static void main(String[] args) {
	try {
		makeSynchronousCallOverHttps("https://my-URL");
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

Exception I was getting –


java.util.concurrent.ExecutionException: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name
        at org.apache.http.concurrent.BasicFuture.getResult(BasicFuture.java:68)
        at org.apache.http.concurrent.BasicFuture.get(BasicFuture.java:94)
        at com.DataProcesser.makeAsyncCall(DataProcesser.java:199)
        at com.DataProcesser.processLead(DataProcesser.java:89)
        at com.Main.main(Main.java:30)
Caused by: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name
        at sun.security.ssl.ClientHandshaker.handshakeAlert(ClientHandshaker.java:1292)
        at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1747)
        at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1060)
        at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:884)
        at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:758)
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)

Solution :

After going through lots of article and settings, I found that this type of issue is due to the misconfigured servers. And excluding Java other clients discard this handshake issue. In solution to this Oracle suggested to use SNIExtension property of Java, which was introduced in Java 7 and above, and make this false before calling the URL over SSL.

This Can be done by setting the property in java


java -Djsse.enableSNIExtension=false myClass

Or adding the below line in our Java code


System.setProperty("jsse.enableSNIExtension", "false");

After that recompile the code and run.

So our code will change to –

private static String makeSSLCall(final String URL) throws Exception {
		
	System.setProperty("jsse.enableSNIExtension", "false");
	try {
    		SSLContext sslContext = SSLContext.getInstance("SSL");

    		// set up a TrustManager that trusts everything
    		sslContext.init(null, new TrustManager[] { new X509TrustManager() {
    			public X509Certificate[] getAcceptedIssuers() {
    				System.out.println("getAcceptedIssuers =============");
    				return null;
    			}

    			public void checkClientTrusted(X509Certificate[] certs,
    					String authType) {
    				System.out.println("checkClientTrusted =============");
    			}

    			public void checkServerTrusted(X509Certificate[] certs,
    					String authType) {
    				System.out.println("checkServerTrusted =============");
    			}
    		} }, new SecureRandom());

    		HttpsURLConnection.setDefaultSSLSocketFactory(
    				sslContext.getSocketFactory());

    		HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
			public boolean verify(String arg0, SSLSession arg1) {
				System.out.println("hostnameVerifier =============");
				return true;
			}
		});

    		URL url = new URL(URL);
    		URLConnection conn = url.openConnection();
            	BufferedReader reader = 
                new BufferedReader(new InputStreamReader(conn.getInputStream()));
            	String line;
            	while ((line = reader.readLine()) != null) {
                	System.out.println("responseCode-->"+line+" for mailerURL : "+URL);
            	}
    	} catch (Exception e) {
    		e.printStackTrace();
    	} 
}
public static void main(String[] args) {
	try {
		makeSynchronousCallOverHttps("https://my-URL");
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}