Search code examples
javasecuritysslcryptographyjsse

Why do I get a handshake failure between TLS 1.0 client and SSL 3.0 server?


There is a project that uses extensively JSSE.

Depending on a configuration parameter the SSLContext is initialized for SSLv3. Meaning that if the parameter is not set it is SSLv3, otherwise it is TLS.

I noticed some handshake failures occasionally and traced it: If the client negotiated TLS and the server replied with SSLv3, the handshake failed

Why does this happen? I thought that TLS and SSLv3 are pretty much interchangeable. Are they not? If I change server side to always reply TLS is there a chance I will break something?


Solution

  • TLS 1.0 is, internally, SSL 3.1. A client and a server may accept to use either or both; during the handshake, the client sends the highest protocol version it knows of, and the server should select the highest version that it supports that is not always newer than the one sent by the client.

    My guess is that when you configure your client to use TLS, then the client understands it as "use only TLS 1.0": the client sends "3.1", and if the server is configured to respond with "3.0", then the client will quite logically reject the connection.

    What you should do is find a way to configure the server to accept both 3.0 and 3.1, and thus use whatever protocol version was announced by the client. Alternatively, configure the client to declare that it knows 3.1, but such that it also accepts a "downgrade" to 3.0 if the server says so.