2014-04-16 36 views
2

SSLEngine documentation指示如何正確關閉SSL連接。更具體地說,它給出瞭如何處理斷開連接的指令:SSLEngine關機

除了有序關閉之外,還可以在關閉消息交換之前切斷傳輸鏈路的無序關閉。在前面的示例中,當嘗試讀取或寫入非阻塞SocketChannel時,應用程序可能會得到-1。當你到達輸入數據的末尾時,你應該調用engine.closeInbound(),它將通過SSLEngine驗證遠程對象已經從SSL/TLS的角度乾淨地關閉,然後應用程序仍然應該嘗試關閉乾淨通過使用上述程序。

基本上,如果鏈接被切斷,應該調用engine.closeInbound()。但是,這個closeInbound()方法的文檔指出,如果它在從對等方接收到正確的結束消息之前被調用,它將拋出異常。在我看來,如果連接被切斷,這個close_notify消息將永遠不會被接收,所以這個方法總是會拋出異常。

我做測試,做了簡單的關機程序在哪裏socketChannel.read()返回-1,我打電話engine.closeInbound(),我確實得到以下異常:

javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack? 

我缺少什麼?這兩份文件不是矛盾的嗎?

回答

3

我不認爲這兩部分文檔相互矛盾。

當你到你的輸入數據的末尾,你應該調用engine.closeInbound()

這適用於完全關閉並切斷連接。當連接被切斷時,將拋出異常(即,如果在收到close_notify之前調用它)。 如果收到了close_notify(或者連接還沒有開始),則不會拋出此異常。

我不太確定你是如何進行簡單關機測試的,但你應該先從另一端發送close_notify(例如closeOutbound())。在這種情況下,在得到close_notify之前,你不應該從socketChannel.read()收到-1(然後你不會得到異常)。

(以防萬一,這是興趣,有一個similar question on SSLSocket前一陣子。)

+1

+1感謝您澄清並在您提供的鏈接上提供非常詳細的解答。我希望我可以接受你的答案和EJP的答案,因爲這兩者都幫助我平等。我接受你的,因爲如果是第一個。 –

2

你看錯這一點。

基本上,如果鏈接被切斷,closeInbound()應該被調用。

它根本就沒有這麼說。

上面說的是closeInbound()方法應該始終被稱爲「當你到你的輸入數據的結束」,然後它會檢測任何切斷連接。

如果沒有收到close_notify,它會拋出異常。

+1

+1感謝您澄清並明確指出closeInbound將檢測到已斷開的連接,確認異常並非意外。 –