简体   繁体   中英

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

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 :

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM