为什么 Java 的 SSLSocket 发送版本 2 客户端问候?
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 消息”启动握手。这不会导致使用SSLv2协议,Java根本不支持该协议。
并来自 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为什么要使用它呢?
The SSLSocket.getEnabledProtocols()
method returns the following: [SSLv2Hello, SSLv3, TLSv1]
. And indeed, when I call connect()
and I have SSL debugging turned on, I see that a v2 client hello is used:
main, WRITE: TLSv1 Handshake, length = 81
main, WRITE: SSLv2 client hello message, length = 110
But I have found two (admittedly old) references that say JSSE does not support SSL version 2:
From Fundamental Networking in Java:
'SSLv2Hello' is a pseudo-protocol which allows Java to initiate the handshake with an SSLv2 'hello message'. This does not cause use of the SSLv2 protocol, which is not supported by Java at all.
And from the JSSE Reference Guide:
The JSSE implementation in the J2SDK 1.4 and later implements SSL 3.0 and TLS 1.0. It does not implement SSL 2.0.
Now, my understanding is that version 2.0 client hello should only be sent when the client does support SSL version 2.0. From RFC 2246:
TLS 1.0 clients that support SSL Version 2.0 servers must send SSL
Version 2.0 client hello messages [SSL2] ... Warning: The ability to send Version 2.0 client hello messages will be phased out with all due haste.
So why does Java use it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Sun 的 JSSE 不支持 SSLv2,但它支持
SSlv2ClientHello
,以支持某些需要它的 SSL 服务器。您可以通过将其从启用的协议中删除来将其关闭。IBM 的 JSSE 完全支持 SSLv2。
来自 JSSE 参考指南:
我想“服务器实现”应该读为上面的“SSL 实现”。
编辑:感谢您引用我的书!
Sun's JSSE doesn't support SSLv2 but it supports the
SSlv2ClientHello
, to support some SSL servers that require it. You can turn it off by removing it from the enabled protocols.IBM's JSSE does support SSLv2 entirely.
From the JSSE Reference Guide:
I imagine 'server implementations' should read 'SSL implementations' above.
EDIT: thanks for citing my book!
我遇到了同样的问题,我们的 RCP 应用程序上出现了此错误,它试图访问仅处理 TLS 协议的 nginx。但是我们使用的 openjdk 有一个 TLS 错误,在某些情况下会以:
javax.net.ssl.SSLException: Received fatalalert: bad_record_mac
结尾。所以我试图找到一种使用不同协议(例如 SSLv3)进行握手的方法。起初我以为SSLv2Hello
是握手协议!但事实并非如此!SSLv2从未在sun jdk或openjdk中实现,这个
SSLv2Hello
不是握手的实际协议,它是为了向后兼容(我的猜测是因为某些服务器存在的可能性)并且它将用于协商将用于实际握手的可用协议!在此链接上搜索来自
Stoinov,他很好地概括了答案。
I faced the same issue, we had this error on our RCP application, it was trying to access our nginx which only handle TLS protocols. but openjdk which we use has a bug with TLS which in some case will end in:
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
. So i was trying to find a way to use a different protocol to do the handshake like SSLv3. At first I though thatSSLv2Hello
is the handshake protocols! but it is not!SSLv2 never implemented in sun jdk or openjdk, this
SSLv2Hello
is not the actual protocol for the handshake, it is there for backward compatibility(my guess is because of the probability of existence of some servers) and it will be used for negotiation on the available protocols that will be used for the actual handshake!on this link search for the answer from
Stoinov
, he wrap the answer very well.