SSLHandShakeException No Appropriate Protocol

ChrisianBartram picture ChrisianBartram · Jul 5, 2016 · Viewed 44.9k times · Source

I recently added SSL to my website and it can be accessed over https. Now when my java application tries to make requests to my website and read from it with a buffered reader it produces this stack trace

Im not using a self signed certificate the cert is from Namecheap who uses COMODO SSL as the CA to sign my certificate. im using java 8

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at sun.security.ssl.Handshaker.activate(Handshaker.java:503)
at sun.security.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:1482)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1351)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)

My code is very basic and simply tries to read the page on my site using a buffered reader

 private void populateDataList() {
    try {
        URL url = new URL("https://myURL.com/Data/Data.txt");
        URLConnection con = url.openConnection();
        con.setRequestProperty("Connection", "close");
        con.setDoInput(true);
        con.setUseCaches(false);

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String line;
        int i = 0;
        while((line = in.readLine()) != null) {
            this.url.add(i, line);
            i++;
        }
    }   catch (Exception e) {
        e.printStackTrace();
    }

}

Ive tried adding my SSL certificate to the JVM's Keystore and Ive also even tried to accept every certificate (which defeats the purpose of SSL I know) with this code

 private void trustCertificate() {
    TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
            }
    };
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (GeneralSecurityException e) {
    }
    try {
        URL url = new URL("https://myURL.com/index.php");
        URLConnection con = url.openConnection();
        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String line;
        while((line = br.readLine()) != null) {
            System.out.println(line);
        }

    } catch (Exception e) {

    }
}

Im stumped and any help would be much appreciated!

Answer

automaton picture automaton · Jul 5, 2016
protocol is disabled or cipher suites are inappropriate

The key to the problem lies in that statement. What it basically means is either:

  1. The TLS implementation used by the client does not support the cipher suites used by the server's certificate.
  2. The TLS configuration on the server has disabled cipher suites supported by the client.
  3. The TLS configurations on the client disable cipher suites offered by the server.
  4. TLS version incompatibility between the client and server.

This leads to handshake failure in TLS, and the connection fails. Check one or all of the three scenarios above.