Tomcat – SSL fatal error, handshake failure 40

certificatessltomcattomcat6

  1. Client sends the "Client Hello" msg with those ciphers included in the cipher suite.

            Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
            Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
            Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005)
            Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
            Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)
            Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038)
            Cipher Suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013)
            Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)
    
  2. In the server.xml none of these ciphers appear. Here is the catalina entry:

    Connector port="4443" SSLEnabled="true" acceptCount="20000" maxThreads="5000" allowTrace="false" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="/usr/local/tomcat6/conf/Default-Cert.p12" keystoreType="PKCS12" keystorePass="uuuuuu" ciphers="…"

    and the ciphers are SSL_RSA_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_AES_256_CBC_SHA, SSL_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA

Server sends “Server Hello” selecting “TLS_RSA_WITH_AES_128_CBC_SHA 0x002f)” and after ~1,5 milliseconds Server sends a fatal alert (Handshake Failure (40)).

Can we explain the handshake failure? Is this due to the fact that TLS_RSA_WITH_AES_128_CBC_SHA is not included in the client cipher list?

Best Answer

SSL fatal error, handshake failure 40 indicates the secure connection failed to establish because the client and the server couldn't agree on connection settings. Usually because the client or the server is way too old, only supporting removed protocols/ciphers.

In historic order, the protocols are SSLv2, SSLv3, TLS 1.0, TLS 1.2, TLS 1.3.

From the debugging info and cipher names you gave:

  • The server only did SSL, don't know which subversion. SSL was obsolete since before the question was opened (before 2015), replaced by TLS.
  • The client wanted TLS. In 2015 it could have been TLS 1.0 and/or TLS 1.2.

In this specific case the server was running on abandoned SSL and in dire need of an upgrade. Looks like a tomcat 6 on java 6, indeed obsolete at the time (2015).

If you're reading this in 2020 or later. The absolute minimum version of java for https to work is java 8 (full support for TLS 1.2).

Try curl --tlsv1.2 https://example.org to test which version of TLS are supported by a web server, curl --help to find out what is supported by curl. Note that only TLS 1.2 is widely supported as of 2020 while TLS 1.3 is coming up gradually. It may be difficult to procure a version of curl/openssl that can do older SSL/TLS variants for testing, they were all phased-off due to (serious) security vulnerabilities.

Related Topic