为什么我在TLS 1.0客户端和SSL 3.0服务器之间握手失败?

问题描述:

有一个项目广泛使用JSSE。为什么我在TLS 1.0客户端和SSL 3.0服务器之间握手失败?

根据配置参数,SSLContext初始化为SSLv3。这意味着如果参数未设置则为SSLv3,否则为TLS

我注意到一些握手失败偶尔和追查:如果客户协商TLS和服务器SSLv3应答时,握手失败

为什么会出现这种情况?我认为TLS和SSLv3几乎可以互换。 他们不是?如果我改变服务器端总是回复TLS有没有机会我会打破一些东西?

+0

您的代码是客户端还是服务器端? – 2011-03-26 14:57:08

+0

@GregS:我控制双方。但客户端部分与我的其他https服务器联系 – Cratylus 2011-03-26 21:33:06

TLS 1.0在内部是SSL 3.1。客户端和服务器可能会接受使用其中之一或两者;在握手期间,客户端发送它所知道的最高协议版本,并且服务器应该选择它支持的最高版本,并不总是比客户端发送的版本更新。

我的猜测是,当您配置客户端使用TLS,则客户端将其理解为“用只有 TLS 1.0”:客户端发送“3.1”,如果服务器被配置为与“3.0回应“,那么客户端会非常逻辑地拒绝连接。

你应该做的是找到一种方法来配置服务器接受3.0 3.1,从而使用客户端发布的任何协议版本。或者,配置客户端声明它知道3.1,但如果服务器这样说,它也会接受“降级”到3.0。

+0

因此,SSL3.1和3.0不兼容。是否需要这种(通常)配置,即将服务器配置为接受3.0和3.1还是自定义代码? – Cratylus 2011-03-29 20:30:14

+0

SSL 3.0和3.1的协议不完全相同,但它们共享足够的结构,第一个客户端消息可以同时适用于两者,服务器则可以决定。这通常是一个配置问题。在内部,这应该最终调用'SSLServerSocket.setEnabledProtocols()'接受一个字符串数组,允许指定多个协议(例如''SSLv3“'和''TLSv1”')。 – 2011-03-29 22:03:59

你不说你想通过改变协议参数来达到目的。 SSLv3和TLS1.0非常相似,但仍然不同的协议。 SSLv3中引入的协议协商机制也用于后续协议。底线是在SSLContext.getInstance("proto");中,您应该将proto设置为您愿意支持的最早版本的SSL协议。之后,同行将协商使用他们都支持的协议的最新版本。

+0

不同的协议参数用作更严格的认证指示。它也用于其他部分(例如,使用更安全的号码发生器等等)。我的问题是为什么在为TLS配置的服务器和用SSLv3初始化SSLContext的客户端实现之间协商失败? – Cratylus 2011-03-26 21:42:25