如何在不關閉底層套接字的情況下正常關閉Java SSL會話?關閉SSL而不關閉底層套接字?
這種情況是,Java客戶端連接到(非Java)服務器,設置SSL並將安全證書(用戶名&密碼)發送到服務器。服務器建立一個在這些證書下運行的環境,在這個環境中產生一個新的進程並將套接字句柄傳遞給它,但問題在於這個新進程無法重用現有的SSL連接(並且不能使用SSL會話恢復)...所以我們的想法是在新的進程生成之前關閉SSL,然後用新進程從頭開始重新協商SSL會話。
問題是Java的SSLSocket'sclose()
方法關閉套接字,除了關閉SSL會話(由sending the close_notify alert)。似乎沒有OpenSSL的SSL_shutdown()函數的等價物,它允許打開底層套接字。
我已經嘗試了一些事情來解決這個問題:
使用SSLSocket.startHandshake()第二次,但自動嘗試恢復現有的緩存的SSL會話(這失敗,因爲衍生的服務器進程不知道此會話),並且,雖然有一種方法force resuming SSL sessions or die trying,但沒有辦法使所有緩存的會話無效或禁用緩存的會話。
使用SSLSocketFactory.createSocket()在我的現有套接字的頂部創建
SSLSocket
,其中autoClose
設置爲false。這並不能阻止close()
方法關閉底層套接字,並且我懷疑autoClose
參數只能防止初始握手失敗時套接字被關閉。超過(如上所述)的現有插座創建
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首先應該是什麼?)。
任何有關如何解決此問題的意見或想法都將受到歡迎。
您是否嘗試在後臺使用普通的Socket?例如:`Socket s = new Socket(HOST,PORT); SSLSocket ssl = ...; ssl.connect(s.getRemoteSocketAddress()); ...'? (對我來說,至少它不會關閉「底層」套接字.. *可能我做錯了某些事情:)) – dacwe 2010-12-06 08:23:07
dacwe,盡我所能地說(忽略...片段的一部分),做ssl.connect()將創建到主機的第二個連接,並且套接字`s`根本不會用於SSL通信。 – Caspar 2010-12-07 00:58:13