这是“使用自签名证书和 SSLEngine (JSSE)进行 SSL 握手”的后续问题。
我已经实现了一个 NIO Webserver,它可以在同一个端口上处理 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 等)来说,一切似乎都运行良好。
问题是 IE 6 等较旧的 Web 浏览器和 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 类到底发送了什么?这是 JSSE SSLEngine 可以支持的有效 SSL/TLS 消息吗?我是否必须进行一些预处理或与客户端协商以发送不同的消息?
提前致谢!
更新
感谢 Bruno 和 EJP 以及一些进一步的调试,我对正在发生的事情有了更好的理解。正如布鲁诺正确指出的那样,IE6 和 Java 6 客户端通过 SSLv2 ClientHello 发送。与我之前的评论相反,Java 1.6 中的 SSLEngine 实际上可以解开 SSLv2 消息并生成有效响应以发送回客户端。我之前报告的 SSLException 是我这边的一个错误,与 SSLEngine 无关(我错误地认为客户端已完成发送数据,而当 SSLEngine 期望更多数据解包时,我最终得到一个空的 ByteBuffer)。