简体   繁体   中英

Java 7: SEND TLSv1.2 ALERT: fatal, description = handshake_failure mule

I'm using java 7 , mule 3.7.0 , I've installed Java Cryptography Extension

I'm trying to send a request to a server, but I'm getting:

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:944)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1342)


Cipher Suites: [TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1}
Extension ec_point_formats, formats: [uncompressed]
Extension extended_master_secret
Extension server_name, server_name: [host_name: merchant.payb.lv]
***
entry.worker.04, WRITE: TLSv1 Handshake, length = 136
entry.worker.04, received EOFException: error
entry.worker.04, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
entry.worker.04, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
entry.worker.04, WRITE: TLSv1.2 Alert, length = 2
entry.worker.04, Exception sending alert: java.net.SocketException: Broken pipe (Write failed)
entry.worker.04, called closeSocket()
entry.worker.04, called close()
entry.worker.04, called closeInternal(true)
entry.worker.04, called close()
entry.worker.04, called closeInternal(true)
entry.worker.04, called close()
entry.worker.04, called closeInternal(true)

As I understood the problem is that there's no support for TLSv1.2 , but there should be after I installed Java Cryptography Extension , can anyone help, please?

I've tried:

System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2")
System.setProperty("jdk.tls.client.protocols", "TLSv1,TLSv1.1,TLSv1.2")
System.setProperty("https.cipherSuites", "TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA")

Also tried:

String[] ciphers = new String[2]
ciphers[0] = "TLS_RSA_WITH_AES_256_CBC_SHA256"
ciphers[1] = "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"
SSLSocket.setEnabledCipherSuites(ciphers)

String[] protocols = new String[1]
protocols[0] = "TLSv1.2";
SSLSocket.setEnabledProtocols(protocols)

I'm using java 7, mule 3.7.0, I've installed Java Cryptography Extension

You can't possibly have installed JCE; it's been included in Java builds since 1.5 (equivalent to 5 now). You probably mean you installed the JCE Unlimited Strength Jurisdiction Policy Files (link for j8 because j7 is now archived). These policy files are files that contain a policy for JCE -- and only needed for Oracle-previously-Sun packages of Java.

You don't say exactly what Java version you are using, but your trace suggests it is a RedHat-family build of OpenJDK. If so, the unlimited policy files are not needed and have no effect; OpenJDK was created in 2007 and never subjected to the 'limited' crypto policy that was designed for then-Sun Java last century. (In the last few months Oracle j8, and j9 and j10, have also eliminated most of this 'feature' at last, replacing it with an editable text item that defaults to unlimited .)

As I understood the problem is that there's no support for TLSv1.2, but there should be after I installed Java Cryptography Extension,

The JCE policy files have absolutely no effect on TLS protocol support. Their only effect on TLS is to enable ciphersuites using AES-256, which is different and separate from the protocol -- and as above only matters in (non-recent) Sun/Oracle packages.

Java 7 does implement TLS 1.2 out of the box, but all of the free (gratis) Oracle packages (up to 7u80) disabled it, and 1.1, on client side by default. After end-of-life for the gratis versions, the 'advanced' ie pay-for-support versions reportedly did enable them at 7u131 and I presume OpenJDK builds did the same, but can't check.

According to https://www.ssllabs.com/ssltest/analyze.html?d=merchant.payb.lv that server doesn't actually require AES-256 anyway; it also accepts and even prefers AES-128 suites and would work even for Oracle j7 without the unlimited policy, as long as at least TLS 1.1 is enabled. It doesn't actually require 1.2, but since the effort to enable 1.1 or 1.2 is the same you might as well go for 1.2.

I've tried:
System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2")
System.setProperty("jdk.tls.client.protocols", "TLSv1,TLSv1.1,TLSv1.2")
System.setProperty("https.cipherSuites", "TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA")

https.protocols only applies to connections using HttpsURLConnection (not JSSE directly) and I don't know if mule does that, either in general or on your system. jdk.tls.client.protocols isn't supported by the gratis versions of Oracle j7; it appears to have been added to the paid versions in 7u91 or possibly 7u95, and presumably OpenJDK the same. https.cipherSuites also applies only to HttpsURLConnection and anyway isn't needed because the default ciphersuites are fine for this server; further the server does not support any 3DES suites -- nor ECDH_RSA with any data cipher. (Practically nobody anywhere uses ECDH_RSA; many including this server use ECDHE_RSA and yes that second E for Ephemeral makes a very big and important difference.)

Also tried:
String[] ciphers = new String[2]
ciphers[0] = "TLS_RSA_WITH_AES_256_CBC_SHA256"
ciphers[1] = "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"
SSLSocket.setEnabledCipherSuites(ciphers)
String[] protocols = new String[1]
protocols[0] = "TLSv1.2";
SSLSocket.setEnabledProtocols(protocols)

That's impossible. setEnabledCipherSuites and setEnabledProtocols are nonstatic methods and must be called on an object (instance) not on the class. And it matters critically which object you use. As above, ciphersuites don't need to be changed at all, and the second one you try to set is wrong in two ways.

I can't reproduce your trace. It logs WRITE: TLSv1 Handshake (meaning 1.0) for the ClientHello, but you have concealed the data that would confirm whether it truly is 1.0. When I test with 7u80 (with unlimited policy, and without mule) defaulting to 1.0, it gets EOF like you do, but it then logs SEND TLSv1 ALERT and WRITE: TLSv1 Alert -- NOT TLSv1.2 . And when I test with 7u80 and enabling 1.2 correctly, it connects successfully, as expected. My only theory consistent with this evidence is that you didn't enable 1.2 correctly and tampered with the log.

Go to connector configuration of HTTP in TLS tab ,There is option called Enabled Protocol.

Just Put the value TLSv1.2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM