-->

SSL握手与旧客户端使用的SSLEngine(JSSE)(SSL Handshaking With

2019-07-29 00:46发布

这是一个后续问题“ SSL握手使用自签名的证书和SSLEngine的(JSSE) ”。

我实现了一个网络服务器NIO可在同一个端口上处理SSL和非SSL消息。 为了SSL和非SSL消息之间进行区分,我检查入站请求的第一个字节,看它是否是一个SSL / TLS消息。 例:

byte a = read(buf);
if (totalBytesRead==1 && (a>19 && a<25)){
    parseTLS(buf);
}

在parseTLS()方法我实例化的SSLEngine,启动握手,包装/解包的消息,等一切都显得做工精细大多数现代Web浏览器(Firefox 10,IE 9,Safari 5的,等等)。

问题是,旧的Web浏览器如IE 6和类似Java的URLConnection类库似乎会以不同启动SSL / TLS握手。 例如,从IE 6的前几个字节看起来像这样(十六进制的值):

80 4F 01 03 00 ...

如果我将消息传递给了SSLEngine的,它似乎并没有认识到的消息,并抛出一个异常。

javax.net.ssl.SSLException: Unsupported record version Unknown-0.0

那么究竟什么是IE 6和Java的URLConnection类在发送? 这是一个有效的SSL / TLS消息的JSSE的SSLEngine能支持吗? 我必须做一些预处理或与客户协商发送不同的信息?

提前致谢!

UPDATE

感谢布鲁诺和EJP和一些进一步的调试我有一个更好的了解这是怎么回事的。 正如布鲁诺正确地指出,在IE6和Java 6个客户端发送一个以上的SSLv2客户问候。 相反,我早先的评论一个,在Java 1.6的SSLEngine其实可以解开的的SSLv2消息,并生成发送回客户端有效的响应。 我先前报告的异常SSLException是站在我这边的错误,无关与SSLEngine的(我错误地假定客户端已完成了发送数据,我结束了在SSLEngine的期待更多的数据来解开一个空字节缓冲区)。

Answer 1:

这看起来像一个的SSLv2客户端Hello(参见TLS规范) :

支持SSL 2.0版服务器TLS 1.1客户端必须发送SSL 2.0版客户端的Hello报文[SSL2。 如果他们想支持SSL相同的连接端口上2.0客户端TLS服务器应该接受任何客户端问候格式。 从2.0版规范的唯一的偏差是有三个值,并在密码规范更多的加密类型的支持指定版本的能力。

  • 80 4F是长度和高比特必须被设置为1(见msg_length描述 )。
  • 01是消息类型(客户端Hello)
  • 03 00是最高的支持版本(这里的SSLv3)

由于Java 7, 这是现在默认情况下禁用 。

编辑:

只是为了澄清,这是不是一个真正的客户端的SSLv2你好,这是在格式的SSLv2客户端对你好的SSLv3。 在这种情况下,服务器会返回一个(适当的)的SSLv3服务器Hello回复(对应于03 00请求的版本号)。 这同样也适用于TLS 1.0,1.1和1.2,虽然这种格式的使用逐渐弃用。

一个JSSE 7 SSLServerSocket仍然会明白这样的客户机问候,并与在SSLv3 / TLS1.x服务器问候适当的答复。



文章来源: SSL Handshaking With Older Clients Using SSLEngine (JSSE)