Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSLHandshakeException while connecting to a https site

I am trying to record a https site through jmeter (version 2.13, java version - 1.8u31) and I am getting SSLHandshakeException while connecting to a https site. The error message is

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:2011)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1113)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:436)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
    at org.apache.jmeter.protocol.http.sampler.MeasuringConnectionManager$MeasuredConnection.open(MeasuringConnectionManager.java:107)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:643)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeRequest(HTTPHC4Impl.java:517)
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:331)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1146)
    at org.apache.jmeter.protocol.http.proxy.Proxy.run(Proxy.java:240)  

I have turned on debug logging for SSL but I wasn't able to understand the root cause. It seems that the java client sends the ClientHello but does not receive the ServerHello message (where the server chooses the highest version of SSL and the best cipher suite that both the client and server support and sends this information to the client). I see differences between the protocol versions being sent, read and received by the client (TLSv1.1 vs TLSv1.2)

Is this the root cause ? If so, how can I fix it?

The logs are pasted here - Java SSLHandshakeException Logs - Pastebin.com

Update

As @Anand Bhatt suggested, I analyzed the site with ssllabs and understood the following

  1. The server does not support TLSv1.2 which is supported by java 8
  2. The server supports only one cipher suite - TLS_RSA_WITH_AES_256_CBC_SHA
  3. Java 8u31 doesn't support the cipher suite that the server supports and that's most probably the issue.

Does that sound right? If so, how do we make the java 8 client support the cipher suite that the server supports?

like image 538
Andy Dufresne Avatar asked Feb 11 '23 02:02

Andy Dufresne


1 Answers

SSLlabs is apparently testing "out of the box" support. Java crypto has a crock dating back to the 1990s when the US government severely restricted export of crypto software, and as a result the JRE (or JDK) as distributed by then-Sun now-Oracle does not permit use of 256-bit symmetric encryption, which your server is demanding. You must download and install the "JCE Unlimited Strength Jurisdiction Policy Files" for your Java (major) version; 8 is at http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html . The README in the file gives longwinded details, but basically you replace two tiny jar files in JRE/lib/security.

TLSv1.2 is not a real issue now. TLS protocol automatically negotiates the highest version supported (and enabled) by both ends. Java 8 implements SSLv3, TLSv1.0, TLSv1.1 and TLSv1.2, but recent updates (8u31 or 7u75 and up) disable SSLv3 by default because of POODLE; you can re-enable it if you choose, but you should be reluctant to. (Java 7 implements the same protocol versions, but client by default disables 1.1 and 1.2 because of compatibility concerns at its release several years ago.)

However, because of POODLE and BEAST some security authorities no longer accept SSLv3 and TLSv1.0 as adequately secure; an important example is credit and debit cards, as detailed in https://security.stackexchange.com/a/87077/39571 . TLSv1.2 includes some technical improvements over 1.1, making it preferred today, and there might be future discoveries that make those improvements crucial; if your server can't support 1.2 (and maybe higher) at that point you would be in trouble. Similarly the fact that the server's only supported suite uses plain-RSA key-exchange, i.e. NOT forward secrecy, is considered suboptimal now, and over time may become unacceptable.

keytool (at least with the normally used keystore and truststore files) has nothing to do with symmetric cryptography. It could likely be relevant if the server uses a CA root (or more exactly and slightly more general, trust anchor) that your JRE and/or application does not trust, and/or if the server wants client authentication at SSL/TLS level, which is fairly rare. (Most websites authenticate at the web-application level, or at least HTTP level, if at all.) SSLLabs checking of the server cert chain (and several other things also) is generally stricter than Java's, and they didn't complain in that area, so it's unlikely you have a problem there.

like image 127
dave_thompson_085 Avatar answered Feb 13 '23 07:02

dave_thompson_085