這是針對「SSL Handshaking Using Self-Signed Certs and SSLEngine (JSSE)」的後續問題。使用SSLEngine(JSSE)與舊客戶端的SSL握手
我已經實現了一個NIO網絡服務器,可以在同一個端口上處理SSL和非SSL消息。爲了區分SSL和非SSL消息,我檢查入站請求的第一個字節以查看它是否爲SSL/TLS消息。例如:
byte a = read(buf);
if (totalBytesRead==1 && (a>19 && a<25)){
parseTLS(buf);
}
在parseTLS()方法我實例的SSLEngine,發起握手,渦卷/解包消息等一切都顯得很好地工作對於大多數現代網絡瀏覽器(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消息嗎?我是否必須做一些預處理或與客戶協商發送不同的信息?
在此先感謝!
UPDATE
感謝布魯諾和EJP和一些進一步的調試我有一個更好的瞭解這是怎麼回事的。正如Bruno正確指出的那樣,IE6和Java 6客戶端通過SSLv2 ClientHello進行發送。與我之前的一個評論相反,Java 1.6中的SSLEngine實際上可以打開SSLv2消息,並生成一個有效的響應以發送回客戶端。我之前報告的SSLException是我的錯誤,與SSLEngine無關(我錯誤地認爲客戶端已經完成了數據發送,當SSLEngine期待更多數據解包時,我最終得到了一個空的ByteBuffer)。
謝謝。根據[http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#Introduction](JSSE參考指南),SUN的SSLEngine不支持SSLv2。那麼我應該怎樣發回客戶?只需關閉連接? – Peter 2012-04-17 20:27:04
它不支持,但它確實支持使用此SSLv2 ClientHello啓動的更高版本的SSL/TLS(提供支持的版本,它指示SSLv3或TLS 1.x):它將以SSLv3 ServerHello回覆該消息,以' 80 4F 01 03 00'。 – Bruno 2012-04-17 20:28:35
對不起,我太早點擊了輸入鍵。所以你說我應該使用SSLv3 ServerHello來響應SSLv2 ClientHello? – Peter 2012-04-17 20:34:59