Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSL connection failing for Java 7

Tags:

I am attempting to create an SSL connection to a remote server using Java 7 and I'm receiving the following exception:

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake     at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)     at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)     at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)     at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)     at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)     at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)     at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)     at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)     at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)     at java.io.BufferedWriter.flush(BufferedWriter.java:254)     at ssl7.Client.main(Client.java:22) Caused by: java.io.EOFException: SSL peer shut down incorrectly     at sun.security.ssl.InputRecord.read(InputRecord.java:482)     at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927) 

When I rerun the code using Java 6, there is no exception. I have found references to this problem elsewhere on StackOverflow but my situation comes with a twist. The client code, which fails with Java 7 is

public class Client {      public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {         try {             SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();             SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("login.solon.com", 443);                 OutputStream outputstream = sslsocket.getOutputStream();             OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);             BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);                 bufferedwriter.write("hello\n");                 bufferedwriter.flush();         } catch (Exception exception) {             exception.printStackTrace();         }     } } 

When I add the line

sslsocket.setEnabledCipherSuites(new String[] {"SSL_RSA_WITH_RC4_128_MD5"}); 

after creating the socket, it works.

now, SSL_RSA_WITH_RC4_128_MD5 exists in the original set of cipher suites so all I've done is add restrictions. Restricting the cipher suites is not a viable solution in the long run. Can anyone explain what is going on here?

The full debug log is:

keyStore is :  keyStore type is : jks keyStore provider is :  init keystore init keymanager of type SunX509 trustStore is: C:\Temp\keystore\clientkeystore trustStore type is : jks trustStore provider is :  init truststore adding as trusted cert:   Subject: CN=W, OU=D, O=S, L=H, ST=I, C=IL   Issuer:  CN=W, OU=D, O=S, L=H, ST=I, C=IL   Algorithm: DSA; Serial number: 0x4a6e05b7   Valid from Mon Oct 07 10:22:54 EEST 2013 until Sun Jan 05 09:22:54 EET 2014  adding as trusted cert:   Subject: CN=login.solon.com, OU=Domain Validated, OU=Thawte SSL123 certificate, OU=Go to https://www.thawte.com/repository/index.html   Issuer:  CN=Thawte DV SSL CA, OU=Domain Validated SSL, O="Thawte, Inc.", C=US   Algorithm: RSA; Serial number: 0x3012ec22473f20aa2cdc4bf7fe2d22f4   Valid from Wed Feb 13 02:00:00 EET 2013 until Thu Apr 14 02:59:59 EEST 2016  adding as trusted cert:   Subject: CN=W, OU=D, O=S, L=H, ST=I, C=IL   Issuer:  CN=W, OU=D, O=S, L=H, ST=I, C=IL   Algorithm: RSA; Serial number: 0x5864235a   Valid from Mon Oct 07 10:28:06 EEST 2013 until Sun Jan 05 09:28:06 EET 2014  trigger seeding of SecureRandom done seeding SecureRandom Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 Allow unsafe renegotiation: true Allow legacy hello messages: true Is initial handshake: true Is secure renegotiation: false %% No cached client session *** ClientHello, TLSv1 RandomCookie:  GMT: 1381093608 bytes = { 221, 239, 107, 239, 150, 213, 224, 210, 101, 229, 42, 58, 92, 9, 151, 0, 128, 105, 0, 55, 53, 224, 90, 111, 130, 175, 61, 121 } Session ID:  {} Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] Compression Methods:  { 0 } Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1} Extension ec_point_formats, formats: [uncompressed] *** [write] MD5 and SHA1 hashes:  len = 149 0000: 01 00 00 91 03 01 52 52   D1 E8 DD EF 6B EF 96 D5  ......RR....k... 0010: E0 D2 65 E5 2A 3A 5C 09   97 00 80 69 00 37 35 E0  ..e.*:\....i.75. 0020: 5A 6F 82 AF 3D 79 00 00   2A C0 09 C0 13 00 2F C0  Zo..=y..*...../. 0030: 04 C0 0E 00 33 00 32 C0   07 C0 11 00 05 C0 02 C0  ....3.2......... 0040: 0C C0 08 C0 12 00 0A C0   03 C0 0D 00 16 00 13 00  ................ 0050: 04 00 FF 01 00 00 3E 00   0A 00 34 00 32 00 17 00  ......>...4.2... 0060: 01 00 03 00 13 00 15 00   06 00 07 00 09 00 0A 00  ................ 0070: 18 00 0B 00 0C 00 19 00   0D 00 0E 00 0F 00 10 00  ................ 0080: 11 00 02 00 12 00 04 00   05 00 14 00 08 00 16 00  ................ 0090: 0B 00 02 01 00                                     ..... main, WRITE: TLSv1 Handshake, length = 149 [Raw write]: length = 154 0000: 16 03 01 00 95 01 00 00   91 03 01 52 52 D1 E8 DD  ...........RR... 0010: EF 6B EF 96 D5 E0 D2 65   E5 2A 3A 5C 09 97 00 80  .k.....e.*:\.... 0020: 69 00 37 35 E0 5A 6F 82   AF 3D 79 00 00 2A C0 09  i.75.Zo..=y..*.. 0030: C0 13 00 2F C0 04 C0 0E   00 33 00 32 C0 07 C0 11  .../.....3.2.... 0040: 00 05 C0 02 C0 0C C0 08   C0 12 00 0A C0 03 C0 0D  ................ 0050: 00 16 00 13 00 04 00 FF   01 00 00 3E 00 0A 00 34  ...........>...4 0060: 00 32 00 17 00 01 00 03   00 13 00 15 00 06 00 07  .2.............. 0070: 00 09 00 0A 00 18 00 0B   00 0C 00 19 00 0D 00 0E  ................ 0080: 00 0F 00 10 00 11 00 02   00 12 00 04 00 05 00 14  ................ 0090: 00 08 00 16 00 0B 00 02   01 00                    .......... main, received EOFException: error main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake main, SEND TLSv1 ALERT:  fatal, description = handshake_failure main, WRITE: TLSv1 Alert, length = 2 [Raw write]: length = 7 0000: 15 03 01 00 02 02 28                               ......( main, called closeSocket() javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake     at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)     at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)     at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)     at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)     at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)     at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)     at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)     at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)     at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)     at java.io.BufferedWriter.flush(BufferedWriter.java:254)     at ssl7.Client.main(Client.java:22) Caused by: java.io.EOFException: SSL peer shut down incorrectly     at sun.security.ssl.InputRecord.read(InputRecord.java:482)     at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)     ... 10 more 

Thanks.

like image 994
twizansk Avatar asked Oct 07 '13 15:10

twizansk


People also ask

What causes SSL handshake failure?

The SSL Handshake Error occurs if the read access has not been granted to the OS, thus preventing the web server from completing authentication. It indicates that the browser's connection to the web server isn't secure.

What happens if SSL handshake fails?

A TLS/SSL handshake failure occurs when a client and server cannot establish communication using the TLS/SSL protocol. When this error occurs in Apigee Edge, the client application receives an HTTP status 503 with the message Service Unavailable.


2 Answers

I have seen this sort of problem before when using an Ubuntu 12.04 server running a Java-based server using its OpenJDK package. (This may have been patched since, as I'm unable to reproduce the problem with the latest updates, but my configuration might be slightly different, I can't remember.)

This was essentially the problem described in this Ubuntu issue.

There was essentially an issue with the EC calculation on the server side, which prevented the connection to be established correctly.

There is a difference in the preference order for the cipher suites between Java 6 and Java 7 (see both tables).

Because TLS_RSA_WITH_AES_128_CBC_SHA is higher than any EC cipher suite in the preference order in Java 6 (and supported by both client and server), it will be chosen when you connect with a Java 6 client.

When you connect with a Java 7 client, some EC cipher suites (e.g. TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA or TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) will be chosen and the server will start to proceed with this (you'd need to see the handshake debug log on the server side to confirm this). The server would then be done with the cipher suite selection process, but fail to go any further because of a subsequent bug when trying to use this cipher suite.

If you have some control over the server (and if it's indeed running a Java-based server), try to upgrade to the latest JRE packages. You can also try the fixes suggested in the Ubuntu issue (especially if it's not using PKCS#11) or to disable the ECDHE cipher suites in the server configuration.

like image 112
Bruno Avatar answered Oct 02 '22 06:10

Bruno


From a glance at your server configuration (https://www.ssllabs.com/ssltest/analyze.html?d=login.solon.com) compared to your list of available cipher suites in Java7, it appears you have only two accepted options for your cipher suite:

TLS_RSA_WITH_AES_128_CBC_SHA TLS_DHE_RSA_WITH_AES_128_CBC_SHA 

Now, TLS_DHE_RSA_WITH_AES_128_CBC_SHA is considered weak, but since your server declares no preference for order, it may be picking this and then failing the handshake. For Java6, it's entirely possible it just happens to be picking a stronger suite. The more options you give it, the more chances you have of giving it a chance to pick a weak cipher, so when you specify a single suite to use, it succeeds. (Although in looking at your server configuration, I'm not sure how you were getting SSL_RSA_WITH_RC4_128_MD5 to succeed as it is apparently not supported.) On that train of thought, perhaps you should try limiting your cipher suites to only:

TLS_RSA_WITH_AES_128_CBC_SHA 

Or more specifically:

sslsocket.setEnabledCipherSuites(new String[] {"TLS_RSA_WITH_AES_128_CBC_SHA"}); 
like image 23
MattSenter Avatar answered Oct 02 '22 06:10

MattSenter