1

I have a Java program connecting to a server with 2 way SSL certificate authentication. It's working fine with Java 7 but failing with Java 6. And unfortunately, our system still using Java 6. So, I am trying to get it work with Java 6.

The connectivity is failing at very first step of SSL mutual authentication transaction. That is ClientHello step. We are receiving a fatal error from the server. As per my analysis, I feel the issue might be related to unsupported Cipher Suites (i.e, server is not supporting the Cipher Suites sent by client) but not sure about that.

I tried using System.setProperty("javax.net.debug", "ssl:handshake"); to debug the issue but the debug information is pointing to specific issue.

I couldn't even get the source code for security classes (example: com.sun.net.ssl.internal.ssl.* package) in Java 6 to debug in the code.

Here is the ssl debug log:

*** ClientHello, TLSv1
RandomCookie:  GMT: 1438890076 bytes = { 65, 109, 167, 225, 235, 81, 235, 118, 35, 88, 126, 146, 201, 181, 233, 118, 222, 126, 190, 170, 247, 232, 166, 222, 98, 157, 165, 150 }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
***
main, WRITE: TLSv1 Handshake, length = 81
main, WRITE: SSLv2 client hello message, length = 110
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT:  fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Exception in thread "main" javax.net.ssl.SSLHandshakeException:     Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1822)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1004)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:476)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at com.castlight.ws.healthfund.welsforgo.WellsForgoTester_JDK6.main(WellsForgoTester_JDK6.java:72)

How to specifically figure out the problem? Is there a way to debug Java 6 security code (example: com.sun.net.ssl.internal.ssl.* package)?

halfer
  • 19,824
  • 17
  • 99
  • 186
Sreenivas
  • 63
  • 3
  • 10
  • Did you check the docs for how Java 6 states this ought to be done? What's the difference? – code_dredd Feb 17 '16 at 18:56
  • Are you setting an `SSLSocketFactory` used for this connection? How do you control things like enabled TLS protocols, cipher suites, etc.? – erickson Feb 17 '16 at 18:56
  • Rather than ciphers which look fine I'd bet the server does not handle SSLv2-*format* hello, which Java6 JSSE uses by default (although only to negotiate newer/better protocols). Since you are using HttpsURLConnection, try setting sysprop https.protocols=SSLv3,TLSv1 . – dave_thompson_085 Feb 17 '16 at 23:45
  • @dave_thompson_085: Yes, Java 6 doesn't seem to be supporting SSLv2. In fact, I was creating sslContext with TLSv1 protocol (_sslContext = SSLContext.getInstance("TLSv1");_), but still its picking SSLv2 for client hello. This seems to be an issue in java 6. And now, it's working by restricting the protocol to TLSv1 with system property _https.protocols=TLSv1_ or by configuring the SSLSocket object (_socket.setEnabledProtocols(new String[]{"TLSv1"});_) Thank you very much for your help. – Sreenivas Feb 18 '16 at 16:41
  • Early versions of Java are messy. Also see [Which Cipher Suites to enable for SSL Socket?](https://stackoverflow.com/q/1037590/608639) – jww Sep 28 '19 at 05:34

1 Answers1

1

First you need to know that java 6 below jdk1.6.115 is not supporting to TLSv1.2. You need to upgrade your JDK vesrion. Also note that you cann't set TLSv1.2 via system property in your code. You will required to set it explicitly using your code. you required to set TLSv1.2 property in your keystore before calling API.