该SSLSocket.getEnabledProtocols()方法返回以下内容: [SSLv2Hello, SSLv3, TLSv1].事实上,当我打电话connect()并打开SSL调试时,我看到使用了一个v2客户端问候:
main, WRITE: TLSv1 Handshake, length = 81
main, WRITE: SSLv2 client hello message, length = 110
Run Code Online (Sandbox Code Playgroud)
但我已经发现了两个(诚然旧)基准说JSSE并不能支持SSL版本2:
来自Java的基础网络:
'SSLv2Hello'是一种伪协议,它允许Java使用SSLv2'hello消息'发起握手.这并不会导致使用的SSLv2协议,这是不是Java的所有支持.
并从JSSE参考指南:
J2SDK 1.4及更高版本中的JSSE实现实现了SSL 3.0和TLS 1.0.它没有实现SSL 2.0.
现在,我的理解是,当客户端2.0版客户端问候应只发送不支持SSL 2.0版.来自RFC 2246:
支持SSL 2.0版服务器的TLS 1.0客户端必须发送SSL 2.0版客户端问候消息[SSL2] ... 警告:发送2.0版客户端问候语消息的能力将逐步淘汰.
那么为什么Java使用它呢?
当我尝试将 Java 8 应用程序连接到网络服务时,我收到 SSLHandshakeException。
www.ssllabs.com说我的网络服务不支持 TLSv1.1 和 TSLv1.2。
所以我用以下命令执行 SSLPoke:
java -Djavax.net.debug=all -Djdk.tls.client.protocols="TLSv1" -Dhttps.protocol="TLSv1" SSLPoke ws.seur.com 443
Run Code Online (Sandbox Code Playgroud)
我得到:
*** ClientHello, TLSv1
RandomCookie: GMT: 1450188882 bytes = { 215, 201, 145, 239, 52, 121, 175, 184, 120, 99, 193, 227, 113, 25, 222, 207, 145, 219, 37, 4, 82, 26, 128, 21, 217, 243, 4, 139 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, …Run Code Online (Sandbox Code Playgroud)