4

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?

Andy Dufresne
  • 5,424
  • 7
  • 53
  • 86
  • 1
    You have specified the Java version or the site that you're trying to connect. Check the site using https://www.ssllabs.com/ssltest/index.html to see if it supports a cipher suite that your client is sending. Also check the handshake simulation section on the test results page to see if there are any issues connecting with your client. – Anand Bhat May 20 '15 at 13:55
  • I have updated my comments with ssllabs analysis. It seems java 8 does not support the cipher suite that the server does. What would be the next step - add the cipher suite through keytool command? – Andy Dufresne May 21 '15 at 05:23

1 Answers1

7

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.

Community
  • 1
  • 1
dave_thompson_085
  • 24,048
  • 4
  • 34
  • 52
  • Thanks for the detailed reply. Updating the jar files resolved the issue. To understand the issue completely can you ellaborate on "the US government severely restricted export of crypto software". I didn't follow how does an algorithm support(TLS_RSA_WITH_AES_256_CBC_SHA) relate to exporting of crypto software? – Andy Dufresne May 22 '15 at 09:49
  • @Andy Historically crypto was used mostly by governments and militaries, and until about 2000 the US govt (and others, but then-Sun was in the US) classified cryptographic hardware and software as weapons that might help enemies destroy us and restricted them; see http://en.wikipedia.org/wiki/International_Traffic_in_Arms_Regulations . Exactly what was covered was complicated and time-varying, but "base" Java ended up limited to 128-bit symmetric crypto, with only US users allowed to upgrade to higher strengths. The ciphersuite you want uses 256-bit AES which is more than 128. – dave_thompson_085 May 23 '15 at 20:20
  • 1
    Breaking news: [you don't need them in Java 9!](http://www.oracle.com/technetwork/java/javase/terms/readme/jdk9-readme-3852447.html#jce) – Franklin Yu Nov 30 '17 at 21:36
  • 1
    @FranklinYu: even more breaking (Oct): also not 8u151+. But there are probably well over a hundred answers on the various Stacks about the JCE-128bits issue; if you want to fix all of them that will be a big job. I have settled for putting the new facts only in new answers. – dave_thompson_085 Dec 02 '17 at 05:30