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

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

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

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

从Java的基础networking :

'SSLv2Hello'是一个伪协议,允许Java用SSLv2'hello消息'发起握手。 这不会导致使用SSLv2协议,这完全不被Java支持。

从JSSE参考指南 :

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

现在,我的理解是2.0版客户端hello应该只在客户端支持SSL版本2.0时发送。 从RFC 2246 :

支持SSL版本2.0服务器的TLS 1.0客户端必须发送SSL版本2.0客户端问候消息[SSL2] … 警告:发送版本2.0客户端问候消息的能力将被全部淘汰。

那么为什么Java使用它?

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

IBM的JSSE完全支持SSLv2。

从JSSE参考指南 :

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

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

编辑:谢谢你引用我的书!