23

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

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

但是我发现了两个(诚然是旧的)参考资料说 JSSE 不支持SSL 版本 2:

来自Java 基础网络

'SSLv2Hello' 是一个伪协议,它允许 Java 使用 SSLv2 'hello message' 发起握手。这不会导致使用 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] ...警告:发送版本 2.0 客户端问候消息的能力将被淘汰,并尽快取消。

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

4

2 回答 2

18

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

IBM 的 JSSE 完全支持 SSLv2。

来自JSSE 参考指南

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

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

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

于 2011-01-14T00:33:30.443 回答
0

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

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

在这个链接上搜索答案Stoinov,他很好地包装了答案。

于 2021-04-09T16:25:34.323 回答