2010-12-06 51 views
5

如何在不關閉底層套接字的情況下正常關閉Java SSL會話?關閉SSL而不關閉底層套接字?

這種情況是,Java客戶端連接到(非Java)服務器,設置SSL並將安全證書(用戶名&密碼)發送到服務器。服務器建立一個在這些證書下運行的環境,在這個環境中產生一個新的進程並將套接字句柄傳遞給它,但問題在於這個新進程無法重用現有的SSL連接(並且不能使用SSL會話恢復)...所以我們的想法是在新的進程生成之前關閉SSL,然後用新進程從頭開始重新協商SSL會話。

問題是Java的SSLSocket'sclose()方法關閉套接字,除了關閉SSL會話(由sending the close_notify alert)。似乎沒有OpenSSL的SSL_shutdown()函數的等價物,它允許打開底層套接字。

我已經嘗試了一些事情來解決這個問題:

  1. 使用SSLSocket.startHandshake()第二次,但自動嘗試恢復現有的緩存的SSL會話(這失敗,因爲衍生的服務器進程不知道此會話),並且,雖然有一種方法force resuming SSL sessions or die trying,但沒有辦法使所有緩存的會話無效或禁用緩存的會話。

  2. 使用SSLSocketFactory.createSocket()在我的現有套接字的頂部創建SSLSocket,其中autoClose設置爲false。這並不能阻止close()方法關閉底層套接字,並且我懷疑autoClose參數只能防止初始握手失敗時套接字被關閉。

  3. 超過(如上所述)的現有插座創建SSLSocket,然後創建第二SSLSocket與衍生的進程爲SSL握手使用(從一個新的SSLContext)。這會失敗,因爲當服務器發送close_notify警報(產生子流程之前)時,Java會關閉套接字。

我一直在使用它聽到的SSLEngine,但我也看到了(雖然源目前躲開我),這是一個很大的痛苦精力編寫了一個正確的SSL實現了TCP/IP的,它當我需要的只是一個版本SSLSocket其不叫super.Close()似乎是矯枉過正。

然而,SSLSocket不會出現,甚至覆蓋close()(根據javadoc的),所以我不能確定它是如何掛鉤的時候似乎沒有成爲對Socket註冊靠近聽衆任何支持close()方法。

公司政策規定不能使用第三方加密庫,所以我不能轉向另一種SSL實現,例如Bouncy Castle來解決該問題。

如果我們無法得到當前的1插槽設計的工作,另一種方法是重寫客戶端&服務器使用2個獨立的套接字(這在必須抵制拒絕服務和人爲干擾方面變得相當混亂)中間人攻擊,而不是SSL首先應該是什麼?)。

任何有關如何解決此問題的意見或想法都將受到歡迎。

+0

您是否嘗試在後臺使用普通的Socket?例如:`Socket s = new Socket(HOST,PORT); SSLSocket ssl = ...; ssl.connect(s.getRemoteSocketAddress()); ...'? (對我來說,至少它不會關閉「底層」套接字.. *可能我做錯了某些事情:)) – dacwe 2010-12-06 08:23:07

+0

dacwe,盡我所能地說(忽略...片段的一部分),做ssl.connect()將創建到主機的第二個連接,並且套接字`s`根本不會用於SSL通信。 – Caspar 2010-12-07 00:58:13

回答

2

這並不關閉底層套接字

是它停止close()方法 。根據文件。

我懷疑自動關閉 參數僅防止插座 從當初始 握手失敗被關閉。

不可以。它阻止關閉底層套接字。根據文件。

向我們展示一些代碼。

+0

我的錯誤,你是對的。 `SSLSocket.close()`javadoc可能不會說關閉SSL通信的任何事情,SSLSocket`的Eclipse大綱視圖不顯示`close`方法(也許它不顯示沒有源附件的已編譯類的重寫方法),但是`SSLSocket.close()`不會覆蓋`Socket.close()`的功能。 – Caspar 2010-12-07 01:07:09

2

您應該可以使用普通的底層套接字(#3),因爲這是使用Clear Control Channel的FTP實現的功能。

請記住,您嘗試執行的操作使您打開兩個SSL會話之間的中間人攻擊,除非您在兩者之間傳遞一些祕密信號以表示身份驗證仍然有效。

  1. 使用網絡麻煩(ARP中毒?)成爲客戶端和服務器之間的代理。
  2. 雙向轉發數據包,直到認證完成並且SSL會話結束。 (任何SSL ALERT都會告訴結束,我們不需要解密內容)。
  3. 關閉客戶端的套接字,使其錯誤。
  4. 做我自己的與服務器的SSL協商。
  5. 繼續使用客戶憑證進行操作。