Java – How to bypass SSLProtocolException: handshake alert: unrecognized_name

With the release of Java SE 7 the Server Name Indication (SNI) extension was introduced as a default in the JSSE client. This enables TLS clients to connect to virtual servers (SNI is explained in RFC 4366 and I am not going to go into the specifics).

Since the “uprising” of SSL I have come across many B2B sites (including financial institutions) where their Ops department could not figure out how to properly configure SSL and it is very common to receive the following error:

Although changing SSL configuration is a simple 2 minute fix, hosting providers (I am looking at you Afrihost and MWeb) are just not capable of resolving this for their clients. This leaves then only two options:

  1. Reject the integration due to SSL errors
  2. Find a Java “workaround”

In Java there are really just two options to “fix” this:

Disable SNI across the JVM

This is a quick fix if you can not change code and will affect the entire JVM. Just pass “-Djsse.enableSNIExtension=false” into the JVM to disable the JSSE SNI extension entirely.

Disable on connection level

If you have access to the URLConnection, this is super simple: We will use our own Hostnameverifier:

The custom-class:

The above solution is a really elegant way of allowing to skip the SNI negotiation in “trusted” cases where you are not able to convince the source-system to properly configure SSL.

 

Print Friendly
  • Omega Saitama

    It is not working here!

  • Omega Saitama

    My code:

    /**
    * Create a trust manager that does not validate certificate chains
    */
    final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
    @Override
    public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string) throws CertificateException {
    }

    @Override
    public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string) throws CertificateException {
    }

    @Override
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    return null;
    }
    }};

    /**
    * Install the all-trusting trust manager
    */
    final SSLContext sslContext = SSLContext.getInstance(“SSL”);
    sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

    /**
    * Create an ssl socket factory with our all-trusting manager
    */
    final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

    /**
    * To maintain the user session that is usually backed by a cookie,
    * so we accept all of them
    */
    CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

    /**
    * All set up, we can get a resource througps now:
    */
    if (proxyIp == null || proxyPort == null) {
    c = (HttpURLConnection) url.openConnection();
    } else {
    SocketAddress socksAddr = new InetSocketAddress(proxyIp, proxyPort);
    java.net.Proxy proxy1 = new java.net.Proxy(java.net.Proxy.Type.SOCKS, socksAddr);

    ProxyAuth auth = new ProxyAuth(proxyUsername, proxyPassword);
    Authenticator.setDefault(auth);

    c = (HttpURLConnection) url.openConnection(proxy1);
    }
    c.setRequestMethod(“GET”);
    c.setConnectTimeout(defaultConnectTimeout);
    c.setReadTimeout(defaultReadTimeout);

    c.setUseCaches(false);
    c.setInstanceFollowRedirects(followRedirects);
    c.setRequestProperty(“Accept”, “text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8”);
    c.setRequestProperty(“User-Agent”, uagent);
    c.setRequestProperty(“Accept-Language”, “*”);
    c.setRequestProperty(“Connection”, “close”);
    c.setRequestProperty(“DNT”, “1”);
    c.setRequestProperty(“Accept-Encoding”, “gzip”);

    if (cookie != null && !cookie.isEmpty()) {
    if (sessionCookies != null && !sessionCookies.isEmpty()) {
    c.setRequestProperty(“Cookie”, cookie + “;” + sessionCookies);
    } else {
    c.setRequestProperty(“Cookie”, cookie);
    }
    } else if (sessionCookies != null && !sessionCookies.isEmpty()) {
    c.setRequestProperty(“Cookie”, sessionCookies);
    }

    HttpURLConnection.setFollowRedirects(followRedirects);
    HttpsURLConnection.setFollowRedirects(followRedirects);

    /**
    * Tell the url connection object to use our socket factory which
    * bypasses security checks
    */
    if (scheme.equalsIgnoreCase(“https”)) {
    try {
    ((HttpsURLConnection) c).setSSLSocketFactory(sslSocketFactory);
    if (!enableSNI) {
    Log.info(Proxy.class, “Deactivating SNI…”);
    ((HttpsURLConnection) c).setHostnameVerifier(new SSLSkipSNIHostnameVerifier());
    }
    } catch (Exception e) {
    Log.debug(Proxy.class, “Problems on the SSL”, e);
    }
    }

    c.connect();