2012-03-13 73 views
1

我正在致力於SSL web server using NIO and the SSLEngine。我能夠成功處理握手併發送/接收應用程序數據。但是,我很難理解如何維護SSL會話狀態。使用JSSE SSL會話管理SSLEngine

我正在使用Firefox 10來測試我的Web服務器。在初始頁面加載時,一切都很好。握手已成功完成。服務器處理客戶端請求併發迴響應。響應清晰地呈現,瀏覽器加載應用程序數據(html,圖像等)。以下是從客戶端發送到服務器的消息的快照。

頁面請求的#1

=============================================== 
== Message 1 
=============================================== 
Client Request: 
    handshake (22) 
    - client_hello (1) 

Server Response: 
    handshake (22) 
    - server_hello (2) 
    - certificate (11) 
    - server_key_exchange (12) 
    - certificate_request (13) 
    - server_hello_done (14) 

=============================================== 
== Message 2 
=============================================== 
Client Request: 
    handshake (22) 
    - certificate (11) 
    - client_key_exchange (16) 

    change_cipher_spec (20) 
    - client_hello (1) 

    handshake (22) 
    *** Encrypted Message **** 

=============================================== 
== Message 3 
=============================================== 
Client Request: 
    application_data (23) 
    *** Encrypted Message **** 

    application_data (23) 
    *** Encrypted Message **** 

Server Response: 
    application_data (23) 
    *** Encrypted Message **** 

同樣,在初始頁面加載,一切都很正常。但是,如果我刷新瀏覽器或轉到其他「頁面」,Firefox將發送應用程序記錄而不是客戶端hello。

頁面請求#2

=============================================== 
== Application Data 
=============================================== 
Client Request: 
    application_data (23) 
    *** Encrypted Message **** 

在這種情況下,所述的SSLEngine當它試圖解開應用程序數據拋出異常。

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection? 

我相信這是因爲我正在實例化每個頁面請求的新SSLEngine。如果我僅將實例化SSLEngine一次並將其設置爲全局/靜態變量,那麼它將成功解開應用程序記錄,並且可以將響應發送回客戶端。我可以刷新頁面,訪問其他頁面等,而不會有任何問題。頁面加載速度非常快,因爲我們正在跳過整個ssl握手過程。

不幸的是,如果我在其他瀏覽器中打開Web服務器(例如IE或Safari)時,SSLEngine中的會話狀態會變得紊亂,並且我的Web服務器無法響應任何新的SSL請求。因此,將SSLEngine實例化一次並使其成爲全局可訪問的靜態變量似乎不是一個可行的選擇。所以...

我該如何迴應第二頁請求(頁面請求#2)?有沒有辦法將第二頁請求(頁面請求#2)與IP地址以外的初始握手請求(頁面請求#1)綁定?第二頁請求(頁面請求#2)中的應用程序數據中是否存在SSL會話ID?

在此先感謝!

回答

3

你必須實例化一個新的SSLEngineSocketChannel,不是每個請求,或每頁面或每個應用程序。 SSLEngine一次只知道一個SSL連接的狀態。

+0

是的,當然!我可以將第二個請求綁定到第一個請求,因爲這些消息使用相同的套接字連接。我不敢相信我之前沒有想到。再次感謝EJP! – Peter 2012-03-14 15:34:47