为什么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实现”。
编辑:谢谢你引用我的书!