简体   繁体   中英

Java 7 with TLSv1.2 connect to LDAPS handshake failure

Currently I am using Java 7 and I am unable to connect to LDAPS. I tried with the code below, but I am still unable to connect:

SSLContext ctx = SSLContext.getInstance("TLSv1.2");
ctx.init(null, null, null);
SSLContext.setDefault(ctx);

Below is the error I get from my program:

2018-04-10 15:21:23,446 INFO [stdout] (EJB default - 1) EJB default - 1, WRITE: TLSv1.2 Handshake, length = 221

2018-04-10 15:21:23,446 INFO [stdout] (EJB default - 1) EJB default - 1, READ: TLSv1.2 Alert, length = 2

2018-04-10 15:21:23,446 INFO [stdout] (EJB default - 1) EJB default - 1, RECV TLSv1 ALERT: fatal, handshake_failure

2018-04-10 15:21:23,446 INFO [stdout] (EJB default - 1) EJB default - 1, called closeSocket()

2018-04-10 15:21:23,446 INFO [stdout] (EJB default - 1) EJB default - 1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure


After that I have tried to run Protocol Test to check supported protocols:

Supported Protocols: 5
  SSLv2Hello
  SSLv3
  TLSv1
  TLSv1.1
  TLSv1.2
Enabled Protocols: 1
  TLSv1

I have added the line below to disable TLSv1 and enable TLSv1.2 in java.security :

jdk.tls.disabledAlgorithms= SSLv3, SSLv2Hello, TLSv1, TLSv1.1

And run again the Protocol Test and it the result is:

Supported Protocols: 5
  SSLv2Hello
  SSLv3
  TLSv1
  TLSv1.1
  TLSv1.2
Enabled Protocols: 0

I have confirmed that my LDAPS server is supported and uses TLSv1.2. I also enabled TLS1.2 in Java Control Panel because whenever I tried to use TLSv1 it causes protocol_version error


My questions are:

  1. What is RECV TLSv1 ALERT: fatal, handshake_failure ?
  2. How to enable TLSv1.2 in supported Protocols?
  3. Edit Does Java 7 or 8 support cipher suite: ECDHE-ECDSA-AES256-GCM-SHA384 ?

I'm using Java 1.7_80.

  1. What is RECV TLSv1 ALERT: fatal, handshake_failure ?

It means we received (in the Java SSL/TLS code, JSSE) an alert from the server with severity fatal and type handshake_failure. Since it occurs immediately after sending one handshake message, if you didn't omit other relevant information from the log extract you posted, we presumably received this alert in response to the ClientHello message, which is the first handshake message sent.

The 'TLSv1' here may be misleading. It is a variable in the SSLSocketImpl object which is initialized to TLSv1 and not updated until the handshake completes, so at this point in time it doesn't accurately indicate the protocol version(s) being used. The preceding log entry, 'READ: TLSv1.2 Alert, length = 2' does show the actual version received and confirms the server is at least trying to do TLS1.2.

What causes handshake_failure? Lots and lots of things. It is practically impossible to tell from this alert what the problem is.

  • Your best option is to look at the server log(s) and find out why it says it sent the alert.

  • Your worst option is to look at the ClientHello we sent -- much of which should have been logged by JSSE prior to the lines you posted -- and consider everything in there, or not in there, whose value or absence the server might dislike, and try changing each of them. Some are moderately easy to change and some are very difficult, so this could take anywhere between hours and weeks.

  • If you have any other client(s) that connect successfully to the same server, an intermediate option is to look at the differences in the ClientHello between the one that works and the one the doesn't, and consider those. As one case of this, if you have or get OpenSSL, commandline openssl s_client is quick and fairly simple to use to test some though not all variations on SSL/TLS handshake.

You can probably guess I recommend the first.

  1. How to enable TLSv1.2 in supported Protocols?

You don't need to enable it in supported; you need to enable it in enabled protocols and you already did. Using SSLContext.getInstance("TLSv1.2") is one way. In Java 8 but not (edit) free Oracle updates of 7, using the sysprop jdk.tls.client.protocols is another way. (7u95 up implement this sysprop, but for Oracle 7 updates above 7u80 require payment. If OpenJDK is available on your platform it is often free.) Calling .setEnabledProtocols on the SSLSocket , once you have it, is another way.

  1. Edit Does Java 7 or 8 support cipher suite: ECDHE-ECDSA-AES256-GCM-SHA384? I'm using Java 1.7_80.

Oracle/Sun and OpenJDK 7 do not support GCM ciphersuites. Or to be exact the standard JSSE provider in them does not, and you didn't say anything about changing the providers. (IBM Java uses different providers and I don't know about them, but they mostly use a different naming format.)

Oracle and OpenJDK 8 do support GCM suites. However, older Oracle updates do not support 256-bit AES unless you download and install the 'Unlimited Jurisdiction Policy' files; there are lots of other Qs on this you can find. This was recently fixed; 8u151/152 only needs a text edit not downloading files, and 8u161/162 and up doesn't need any change at all. Neither does Oracle 9, or any OpenJDK.

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