首页 文章

带有TLSv1.2的Java 7连接到LDAPS握手失败

提问于
浏览
0

目前我正在使用Java 7,我无法连接到LDAPS . 我尝试使用下面的代码,但我仍然无法连接:

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

以下是我从程序中得到的错误:

2018-04-10 15:21:23,446 INFO [stdout](EJB默认值 - 1)EJB默认值 - 1,WRITE:TLSv1.2握手,长度= 221 2018-04-10 15:21:23,446 INFO [stdout] (EJB默认值 - 1)EJB默认值 - 1,READ:TLSv1.2警报,长度= 2 2018-04-10 15:21:23,446 INFO [stdout](EJB默认值 - 1)EJB默认值 - 1,RECV TLSv1 ALERT: fatal,handshake_failure 2018-04-10 15:21:23,446 INFO [stdout](EJB default - 1)EJB默认值 - 1,名为closeSocket()2018-04-10 15:21:23,446 INFO [stdout](EJB默认 - 1)EJB默认值 - 1,处理异常:javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure


之后我尝试运行Protocol Test来检查支持的协议:

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

我已添加以下行以禁用TLSv1并在 java.security 中启用TLSv1.2:

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

并再次运行协议测试,结果是:

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

我已确认支持我的LDAPS服务器并使用TLSv1.2 . 我还在Java控制面板中启用了TLS1.2,因为每当我尝试使用TLSv1时都会导致 protocol_version 错误


我的问题是:

  • 什么是 RECV TLSv1 ALERT: fatal, handshake_failure

  • 如何在支持的协议中启用TLSv1.2?

  • Edit Java 7或8是否支持密码套件: ECDHE-ECDSA-AES256-GCM-SHA384

我正在使用Java 1.7_80 .

1 回答

  • 1

    什么是RECV TLSv1警告:致命,握手_失败?

    这意味着我们收到了(在Java SSL / TLS代码中,JSSE)来自服务器的警报,其严重性为致命,类型为handshake_failure . 由于它在发送一个握手消息后立即发生,如果您没有从您发布的日志提取中省略其他相关信息,我们可能会收到此警报以响应ClientHello消息,这是发送的第一个握手消息 .

    这里的'TLSv1'可能会产生误导 . 它是 SSLSocketImpl 对象中的一个变量,它初始化为TLSv1,并且在握手完成之前不会更新,因此在这个时间点它不能准确地指示正在使用的协议版本 . 前面的日志条目'READ: TLSv1.2 Alert, length = 2'确实显示了收到的实际版本,并确认服务器至少尝试执行TLS1.2 .

    What causes handshake_failure? 很多东西 . 实际上不可能从这个警报中判断出问题是什么 .

    • 您最好的选择是查看服务器日志并找出它发送警报的原因 .

    • 你最糟糕的选择是查看我们发送的ClientHello--其中大部分应该在你发布的行之前由JSSE记录 - 并考虑那里的所有内容,或者不在那里,服务器可能不喜欢它们的值或缺席,并尝试更改它们中的每一个 . 有些很容易改变,有些很难,所以这可能需要几个小时到几个星期 .

    • 如果您有任何其他成功连接到同一服务器的客户端,则中间选项是查看ClientHello在工作的客户端与不工作的客户端之间的差异,并考虑这些差异 . 作为这种情况的一个例子,如果您拥有或获得OpenSSL,命令行 openssl s_client 可以快速且相当简单地用于测试SSL / TLS握手的一些但不是所有变体 .

    你可能猜测我推荐的第一个 .

    如何在支持的协议中启用TLSv1.2?

    您不需要在支持中启用它;你需要在启用的协议中启用它,你已经做到了 . 使用 SSLContext.getInstance("TLSv1.2") 是一种方法 . 在Java 8中,但没有(编辑)7的免费Oracle更新,使用sysprop jdk.tls.client.protocols 是另一种方式 . (7u95实现这个sysprop,但是对于7u80以上的Oracle 7更新需要付款 . 如果OpenJDK在你的平台上可用,它通常是免费的 . )在 SSLSocket 上调用 .setEnabledProtocols ,一旦你拥有它,是另一种方式 .

    编辑Java 7或8是否支持密码套件:ECDHE-ECDSA-AES256-GCM-SHA384?我正在使用Java 1.7_80 .

    Oracle / Sun和OpenJDK 7不支持GCM密码套件 . 或者确切地说,它们中的标准JSSE提供程序没有,并且您没有提及有关更改提供程序的任何信息 . (IBM Java使用不同的提供程序,但我不了解它们,但它们大多使用不同的命名格式 . )

    Oracle和OpenJDK 8确实支持GCM套件 . 但是,较旧的Oracle更新不支持256位AES,除非您下载并安装'Unlimited Jurisdiction Policy'文件;你可以找到很多其他的Q.这是最近修好; 8u151 / 152只需要文本编辑而不需要下载文件,而8u161 / 162及以上版本根本不需要任何更改 . Oracle 9或任何OpenJDK都不是 .

相关问题