2

I am having trouble determining why a specific handshake is failing. I am unable to connect to a specific site and have been unable to determine the reason that it is failing. It is working on one of my servers, but not the other. My application is able to successfully connect to other sites with SSL. I've done a lot of searching around, but have had no luck.

Stack Trace

Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2033)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1135)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:730)
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:757)
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:706)
    at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:299)

-Djavax.net.debug=all output

22-Feb-2018 22:07:02.632 INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_NULL_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
trustStore is: /etc/pki/java/cacerts
trustStore type is : jks
trustStore provider is : 
init truststore

... a bunch of "adding as trusted cert" ...

keyStore is : 
keyStore type is : jks
keyStore provider is : 
init keystore
init keymanager of type SunX509
trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
pool-1-thread-2, setSoTimeout(15000) called
pool-1-thread-2, the previous server name in SNI (type=host_name (0), value=www.wta.org) was replaced with (type=host_name (0), value=www.wta.org)
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1502523033 bytes = { 53, 17, 44, 60, 223, 247, 43, 100, 70, 139, 96, 93, 171, 101, 44, 228, 62, 27, 106, 57, 23, 205, 135, 35, 20, 69, 197, 176 }
Session ID:  {}
Cipher Suites: [TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
Extension server_name, server_name: [type=host_name (0), value=www.wta.org]
***
[write] MD5 and SHA1 hashes:  len = 143
0000: 01 00 00 8B 03 03 5A 8F   AF 99 35 11 2C 3C DF F7  ......Z...5.,<..
0010: 2B 64 46 8B 60 5D AB 65   2C E4 3E 1B 6A 39 17 CD  +dF.`].e,.>.j9..
0020: 87 23 14 45 C5 B0 00 00   2C 00 3D 00 6B 00 6A 00  .#.E....,.=.k.j.
0030: 35 00 39 00 38 00 3C 00   67 00 40 00 2F 00 33 00  5.9.8.<.g.@./.3.
0040: 32 00 9D 00 9F 00 A3 00   9C 00 9E 00 A2 00 0A 00  2...............
0050: 16 00 13 00 FF 01 00 00   36 00 0D 00 1E 00 1C 06  ........6.......
0060: 03 06 01 05 03 05 01 04   03 04 01 04 02 03 03 03  ................
0070: 01 03 02 02 03 02 01 02   02 01 01 00 00 00 10 00  ................
0080: 0E 00 00 0B 77 77 77 2E   77 74 61 2E 6F 72 67     ....www.wta.org
pool-1-thread-2, WRITE: TLSv1.2 Handshake, length = 143
[Raw write]: length = 148
0000: 16 03 03 00 8F 01 00 00   8B 03 03 5A 8F AF 99 35  ...........Z...5
0010: 11 2C 3C DF F7 2B 64 46   8B 60 5D AB 65 2C E4 3E  .,<..+dF.`].e,.>
0020: 1B 6A 39 17 CD 87 23 14   45 C5 B0 00 00 2C 00 3D  .j9...#.E....,.=
0030: 00 6B 00 6A 00 35 00 39   00 38 00 3C 00 67 00 40  .k.j.5.9.8.<.g.@
0040: 00 2F 00 33 00 32 00 9D   00 9F 00 A3 00 9C 00 9E  ./.3.2..........
0050: 00 A2 00 0A 00 16 00 13   00 FF 01 00 00 36 00 0D  .............6..
0060: 00 1E 00 1C 06 03 06 01   05 03 05 01 04 03 04 01  ................
0070: 04 02 03 03 03 01 03 02   02 03 02 01 02 02 01 01  ................
0080: 00 00 00 10 00 0E 00 00   0B 77 77 77 2E 77 74 61  .........www.wta
0090: 2E 6F 72 67                                        .org
[Raw read]: length = 5
0000: 15 03 03 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
pool-1-thread-2, READ: TLSv1.2 Alert, length = 2
pool-1-thread-2, RECV TLSv1.2 ALERT:  fatal, handshake_failure
pool-1-thread-2, called closeSocket()
pool-1-thread-2, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
pool-1-thread-2, called close()
pool-1-thread-2, called closeInternal(true)

Application Details

My application is on Java 8 and Tomcat 8.5. My OS is Fedora 24. I am using Jsoup to attempt to download http://www.wta.org/sitemap.xml.gz, but am receiving the handshake failure. I am able to connect to other sites that use SSL though.

What I have tried

  1. I have tried copying the cacerts file from my working server onto my failing server.
  2. I have tried installing Java Cryptography Extension (JCE) Unlimited Strength: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
  3. I attempted to read the output from -Djavax.net.debug=all, but most of it was beyond me.

Most of the ideas came from this post: Received fatal alert: handshake_failure through SSLHandshakeException

UPDATE: I think they ended up fixing their SSL certificate because things just magically started working with no change.

  • Java will usually tell you when no cipher suites are found in common. I think the problem is more likely to be that the server is expecting an `SSLvHello` instead of a `TLSv1.2`-hello. Try adjusting your client so that it supports the following protocols: `TLSv1.2, SSLv2Hello`. (Note that the `SSLv2Hello` is *not* an old, vulnerable protocol... it will just allow an old-style handshake which is incompatible with a TLS-only handshake.) – Christopher Schultz Feb 27 '18 at 14:38
  • 1
    @ChristopherSchultz Java can only tell you what the server said. Very few servers today even accept SSL2 hello and I can't believe any require it. This server clearly responded with TLS1.2 format alert (see 15 03 03 00 02 / 02 28) making that even less likely, and checking with `openssl s_client` or SSLLabs as in the answer proves it does accept TLS1.2. – dave_thompson_085 May 02 '18 at 03:02

1 Answers1

1

When testing the website on SSL Labs, we see what Cipher Suites are allowed. Unluckily, none of them are in the Cipher Suites array sent by your client ([TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_...).

In fact, the server only accepts suites from the high encryption Forward Secrecy list (which is a recommended thing for security reasons).

Are you sure you installed the Unlimited Strength jar files correctly (in $JAVA_HOME\jre\lib\security) and restarted your tomcat ? [here $JAVA_HOME is used by tomcat]

This should allow cipher suites such as TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 which are marked like unavailable but are delivered from the unrestricted set

Rishikesh Darandale
  • 2,512
  • 3
  • 14
  • 32
Eugène Adell
  • 2,644
  • 2
  • 14
  • 30
  • I am confident that I installed it in the right place. When I boot tomcat, it writes `Using JRE_HOME: /usr/lib/jvm/java-openjdk`. In `/usr/lib/jvm/java-openjdk/jre/lib/security`, I made backups of the original local_policy.jar and US_export_policy.jar and then replaced the files with the [JCE ones](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html). Could it be because the JCE is oracle JDK and I have open JDK java? Seems unlikely to be an issue but figured I should ask. – derfsubterfuge Feb 25 '18 at 04:02
  • Yes. Although one says you don't have anything to do to run these ciphers ( https://www.eyrie.org/~eagle/notes/debian/jce-policy.html ) but I didn't try myself. At the same time it seems confirmed by this ( http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/e164409e5948 ) . With Java 9, it's no more unrestricted and it's supposed to work whatever implementation you choose. I can't help more, I won't debug openjdk today. – Eugène Adell Feb 25 '18 at 07:55
  • 1
    Client sent several AES256 suites which proved unlimited-policy was not the problem, and in fact OpenJDK _never_ needed unlimited-policy to start with. (_Oracle_ 8u161+, 9, 10 also don't.) What the server demands and this client doesn't offer is **elliptic-curve** keyexchange (ECDHE_ECDSA), and j8 should do that. @derfsubterfuge: you report using **Fedora**. Make sure you are up to date. Until about 2 years ago, RedHat _removed_ all EC crypto from their packages, apparently for fear of Certicom's patents. – dave_thompson_085 May 02 '18 at 03:01