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
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: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.
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.