为什么Java的SSSocket发送版本2客户端hello?

2022-09-01 23:41:17

该方法返回以下内容:。事实上,当我调用并打开SSL调试时,我看到使用了v2客户端hello:SSLSocket.getEnabledProtocols()[SSLv2Hello, SSLv3, TLSv1]connect()

main, WRITE: TLSv1 Handshake, length = 81
main, WRITE: SSLv2 client hello message, length = 110

但是我发现了两个(公认是旧的)引用,说JSSE不支持SSL版本2:

来自 Java 中的基础网络

“SSLv2Hello”是一个伪协议,它允许Java使用SSLv2“hello message”启动握手。这会导致使用SSLv2协议,Java根本不支持SSLv2协议。

来自JSSE参考指南

J2SDK 1.4 及更高版本中的 JSSE 实现实现了 SSL 3.0 和 TLS 1.0。它不实现 SSL 2.0。

现在,我的理解是,仅当客户端支持 SSL 版本 2.0 时,才应发送 2.0 版客户端问候。来自 RFC 2246

支持 SSL 版本 2.0 服务器的 TLS 1.0 客户端必须发送 SSL 版本 2.0 客户端问候消息 [SSL2] ...警告:发送 V2.0 客户端问候消息的功能将被逐步淘汰,并立即停止。

那么Java为什么要使用它呢?


答案 1

Sun 的 JSSE 不支持 SSLv2,但它支持 ,以支持一些需要它的 SSL 服务器。您可以通过将其从启用的协议中删除来将其关闭。SSlv2ClientHello

IBM的JSSE确实完全支持SSLv2。

摘自 JSSE 参考指南

例如,一些较旧的服务器实现只说SSLv3,不理解TLS。理想情况下,这些实现应该协商到SSLv3,但有些只是挂断。为了向后兼容,某些服务器实现(如 SunJSSE)发送封装在 SSLv2 ClientHello 数据包中的 SSLv3/TLS ClientHellos。某些服务器不接受此格式,在这些情况下,请使用 setEnabledProtocols 来禁用封装的 SSLv2 ClientHellos 的发送。

我想“服务器实现”应该读成上面的“SSL实现”。

编辑:感谢您引用我的书!


答案 2

我遇到了同样的问题,我们在RCP应用程序上遇到了这个错误,它试图访问我们的nginx,它只处理TLS协议。但是我们使用的openjdk有一个TLS错误,在某些情况下会以:结尾: 。所以我试图找到一种方法来使用不同的协议来像SSLv3一样握手。起初,我虽然这是握手协议!但事实并非如此!javax.net.ssl.SSLException: Received fatal alert: bad_record_macSSLv2Hello

SSLv2从未在sun jdk或openjdk中实现过,这不是握手的实际协议,它是为了向后兼容(我的猜测是因为某些服务器存在的可能性),它将用于协商将用于实际握手的可用协议!SSLv2Hello

在这个链接上搜索答案,他把答案包裹得很好。Stoinov