这是"使用自签名Certs和SSLEngine (JSSE)的SSL握手“的后续问题。
我已经实现了一个NIO non服务器,它可以在同一个端口上处理SSL和非SSL消息。为了区分SSL消息和非SSL消息,我检查入站请求的第一个字节,看看它是否是SSL/TLS消息。示例:
byte a = read(buf);
if (totalBytesRead==1 && (a>19 && a<25)){
parseTLS(buf);
}在parseTLS()方法中,我实例化了一个SSLEngine,启动了握手、包装/解包消息等等。对于大多数现代web浏览器(火狐10、IE9、Safari 5等),一切似乎都很好。
问题是,像IE6这样的较旧的web浏览器和Java的URLConnection类这样的库似乎以不同的方式启动SSL/TLS握手。例如,IE6的前几个字节如下所示(十六进制值):
80 4F 01 03 00 ...如果我将消息传递给SSLEngine,它似乎无法识别该消息并引发异常。
javax.net.ssl.SSLException: Unsupported record version Unknown-0.0那么IE6和Java的URLConnection类到底发送了什么呢?这是JSSE SSLEngine可以支持的有效的SSL/TLS消息吗?我是否需要做一些预处理或与客户协商,以发送不同的信息?
提前感谢!
更新
多亏了Bruno和EJP以及一些进一步的调试,我才能更好地理解正在发生的事情。正如布鲁诺正确指出的那样,IE6和Java6客户端正在发送一个SSLv2 ClientHello。与我前面的一个注释相反,Java1.6中的SSLEngine实际上可以打开SSLv2消息并生成一个有效的响应来发送回客户端。我在前面报告的SSLException是我这边的一个错误,与SSLEngine无关(我错误地假设客户端已经完成了数据的发送,而当SSLEngine期待更多的数据被打开时,我得到了一个空的ByteBuffer )。
发布于 2012-04-17 20:01:38
支持SSL2.0服务器的TL1.1客户端必须发送SSL2.0客户端hello消息SSL2。如果TLS服务器希望在相同的连接端口上支持SSL2.0客户端,那么TLS服务器应该接受任何一种客户机hello格式。与Version2.0规范的唯一偏差是能够指定一个值为3的版本,并在CipherSpec中支持更多的加密类型。
80 4F是长度,高位必须设置为1(参见描述)。01是消息类型(客户机你好)03 00是最受支持的版本(这里是SSLv3)从Java 7,默认情况下,这现在是禁用的。。
编辑:
澄清一下,这并不是真正的SSLv2客户机Hello,而是SSLv3的SSLv2格式的客户机Hello。在这种情况下,服务器将使用(适当的) SSLv3服务器Hello (对应于03 00请求的版本号)进行回复。TLS1.0、1.1和1.2也是如此,尽管这种格式的使用逐渐被废弃。
JSSE 7 SSLServerSocket仍然会理解这样的客户机Hello,并使用SSLv3 3/TLS1.xServerHello进行适当的回复。
https://stackoverflow.com/questions/10196436
复制相似问题