我们必须使用 HTTPS 将我们的应用程序(用 Java 8 编写)连接到一些非常旧的服务器。作为 Java 8,我们的客户端支持 TLSv1.2、TLSv1.1、TLSv1 和 SSLv3。当然,它更喜欢使用 TLSv1.2,因为它是最新的协议。
但是,服务器 (Oracle-HTTP-Server 11.1.1.7) 仅支持 TLSv1 和 SSLx。此外,它支持的密码套件选择非常有限,但仍有一个共同的套件可以与 TLSv1 一起使用:SSL_RSA_WITH_3DES_EDE_CBC_SHA(又名 TLS_RSA_WITH_3DES_EDE_CBC_SHA)。
但是,直接连接会因服务器终止握手而失败。我们得到的调试输出(在客户端)如下所示:
main, WRITE: TLSv1.2 Handshake, length = 265
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1.2 ALERT: fatal, close_notify
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLException: Received fatal alert: close_notify
对我来说,看起来服务器甚至没有尝试回退到 TLSv1:一旦客户端声明 TLSv1.2 为首选,服务器就会退出。
相比之下,当我们在客户端中明确禁用 TLSv1.2 和 TLSv1.1,从而使 TLSv1 成为首选选项时,握手成功。
我们还尝试连接到另一个不知道 TLSv1.2 和 TLSv1.1 的旧服务器,但这里的连接按预期工作:即使客户端说它更喜欢 TLSv1.2,他们同意服务器使用 TLSv1,作为最佳通用协议:
main, WRITE: TLSv1.2 Handshake, length = 269
main, READ: TLSv1 Handshake, length = 85
...
问题:服务器是否有责任从客户端支持的 TLS/SSL 协议列表中进行选择?我可以对服务器维护人员说行为不端的是服务器,而不是我们的客户端吗?