客户端 Hello 后的 SSL 握手致命错误

Posted

技术标签:

【中文标题】客户端 Hello 后的 SSL 握手致命错误【英文标题】:SSL Handshake fatal error after Client Hello 【发布时间】:2016-05-04 15:54:32 【问题描述】:

我正在尝试对由内部 CA 签名的服务器进行 https 调用。尽管在信任库中添加了根证书,但我无法使其正常工作,因此我将 trustManager 设置为信任所有证书并暂时禁用主机名验证。curl --insecure 调用有效。 使用-Djavax.net.debug=all,客户端打招呼后握手失败

*** ClientHello, TLSv1 ... ... main, READ: TLSv1 Alert, length = 2 main, RECV TLSv1 ALERT: fatal, handshake_failure main, 调用 closeSocket() main, 处理异常: javax.net.ssl.SSLHandshakeException:收到致命警报: handshake_failure main, 称为 close() main, 称为 关闭内部(真)

堆栈跟踪是:

javax.net.ssl.SSLHandshakeException:收到致命警报: 握手失败在 sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 在 sun.security.ssl.Alerts.getSSLException(Alerts.java:154) 在 sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959) 在 sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077) 在 sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) 在 sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) 在 sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)

我正在使用

获取 SSL 上下文
SSLContext sslContext = SSLContext.getInstance("TLS");

任何帮助将不胜感激。

PS:我正在使用 java7

【问题讨论】:

在验证证书信任之前会发生握手失败。检查两端都启用了 TLS,并且有一个通用的密码套件。查看服务器端的日志,检查与wireshark的协商。 请使用-Djavax.net.debug=ssl,handshake 运行您的客户端并将结果发布到您的问题中。 【参考方案1】:

在 4 年后为我自己的问题添加答案。

我不记得确切的问题是什么,但握手失败并没有单一原因 - 在 ClientHello 之后发生握手失败的最可能原因是客户端和服务器无法就通用协议达成一致或用于继续握手的密码套件。

调试此类 SSL 问题的最简单方法是使用 tcpdump 捕获网络流量并在 Wireshark 中对其进行分析。我们可以检查 ClientHello 并找出正在使用的协议、它宣传支持的密码套件等。

【讨论】:

Wireshark 很棒,但对于 Java,javax.net.debug 提供了相同的信息等等。是的,handshake_failure 可能有很多原因,是的,在这种情况下协议兼容性很可能,特别是因为 j7 于 2011 年发布实现 TLS1.1 和 1.2 但默认情况下在客户端禁用它们,因为兼容性问题,但在几个月内 BEAST 攻击被发布,许多人回应要求 1.1 或更高版本,包括 2015 年所有处理卡支付的网站的支付卡行业委员会(这是大多数)。

以上是关于客户端 Hello 后的 SSL 握手致命错误的主要内容,如果未能解决你的问题,请参考以下文章

客户端 Hello 后 SSL 握手失败服务器 [FIN, ACK]

SSL握手过程详解

在 SSL/TLS 握手中的“server-hello”消息期间选择证书链的逻辑?

详解SSL证书中的SSL握手协议

TLS 致命:握手失败

SSL 握手错误 javax.net.ssl.SSLHandshakeException 收到致命警报 bad_certificate