6

I am trying to call an SSL protected web service running on JDK7 / WildFly 8.2 with a Java 6 (update 31) based client.

The first problem I encountered on the client was:

javax.net.ssl.SSLException: Received fatal alert: unexpected_message

By setting javax.net.debug to all on both sides, I got the following hint on the server side:

javax.net.ssl.SSLHandshakeException: SSLv2Hello is disabled

Quick research shows that,

SSLv2Hello disabled by default on the client: In Java SE 7, SSLv2Hello is removed from the default enabled protocol list on the client.

So I have tried to enable SSLv2Hello on WildFly in standalone.xml:

<https-listener name="https" 
                socket-binding="https" 
                security-realm="UndertowRealm"
                enabled-protocols="SSLv2, SSLv2Hello, TLSv1, TLSv1.1, TLSv1.2"
                />

And the result on the server is:

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

So I realize, I should be trying to force TLS on the client instead of enabling SSLv2Hello on the server. I have tried to set System.setProperty("https.protocols", "TLSv1"); before my web service call with no effect.

What should I configure and how, to get the handshake working?

I have printed the supported cipher suites from the default SSLSocketFactory on the server:

TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
SSL_RSA_WITH_RC4_128_SHA,
TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
TLS_ECDH_RSA_WITH_RC4_128_SHA,
SSL_RSA_WITH_RC4_128_MD5,
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
Daniel Szalay
  • 4,041
  • 12
  • 57
  • 103
  • You should test the server which protocols and chipher suites are supported: https://www.ssllabs.com/ssltest/ – Robert May 11 '15 at 11:30
  • @Robert Since I have a local server I cannot use the tool you provided. I have added a list of the *default* ciphers for the `SSLSocketFactory`. – Daniel Szalay May 11 '15 at 11:47
  • If it is a local server use the tool "sslyze" and/or ask the amin of the server how the server is configured. And if the server does not support TLS1.1/1.2 kick the admin's ass... BTW. Java 6 and 7 are outdated. Only use Java 8. – Robert May 11 '15 at 11:52
  • @Robert WildFly 8.2 supports TLS1.1/1.2 AFAIK. I am not allowed to upgrade Java 6 for the client apps ;( – Daniel Szalay May 11 '15 at 12:02
  • It is probably tempting to vote to close this as 'cannot reproduce', as current versions of Java cannot produce this behaviour,because SSLv2Hello has been removed. But it needs to stay here for historical reasons. We've seen new questions about Java 1.4.1 more than ten years after it came out. – user207421 Feb 14 '18 at 23:33

2 Answers2

2

You don't need to enable SSLv2 at the server. You need to disable the SSLv2Hello pseudo-protocol at the client, by removing SSLv2Hello from the enabled TLS protocols and leaving the others:

System.setProperty("https.protocols", "TLSv1,TLSV1.1,TLSV1.2");

and maybe SSLv3 if that makes it happy: it won't for much longer, so try not to have to do that.

Note that it is a pseudo-protocol. It is not SSLv2, it is a compatibility measure to allow certain arguably broken servers to accept the hello. The session however operates at SSLv3 or above. It is also obsolete.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Caveat: sysprop `https.protocols` only works on code using `HttpsUrlConnection` (including indirectly), or Apache httpclient if the code selects useSystemProperties. Other libraries or standalone code may require a different setting, or even a code change. – dave_thompson_085 Feb 15 '18 at 03:17
0

You could probably enable the SSLv2 protocol at the JVM but that is extremely inadvisable because that is a serious security risk.

The clients are using an outdated and insecure protocol and should be updated to TLSv1.1 or TLSv.1.2. That will require at least Java 7 but Java 8 would be better as Robert mentioned.

More info could be found at https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https including a table of support TLS protocols by version.

aled
  • 21,330
  • 3
  • 27
  • 34
  • You can't enable SSLv2 at the client. Sun/Oracle Java has never supported it. – user207421 Dec 16 '17 at 10:08
  • I should have mentioned that SSLv2Hello was enabled in older Java versions and disabled in Java 7. Still can be reenabled if needed. – aled Dec 18 '17 at 15:18
  • I already mentioned that a month previously. SSLv2Hello is not the same thing as SSLv2. Java has never supported SSLv2. Ergo the clients are not 'using an outdated and insecure protocol'. They are using SSLv2Hello as a compatibility measure. – EJP 1 hour ago – user207421 Feb 14 '18 at 23:53
  • While your answer apparently isn't 100% correct - I still upvoted it for providing the great link on diagnosing https issues – JGlass Feb 15 '19 at 20:02