2012-03-13 14 views
1

私はSSL web server using NIO and the SSLEngineで作業しています。ハンドシェイクを正常に処理し、アプリケーションデータを送受信できます。しかし、私はSSLセッションの状態を維持する方法を理解するのが難しいです。JSSE SSLEngineによるSSLセッション管理

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はクライアントの代わりにアプリケーションレコードを送信します。この場合

ページ要求#2

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

それはアプリケーションデータをアンラップしようとすると、SSLEngineのは例外をスロー。

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

これは、私が各ページリクエストで新しいSSLEngineをインスタンス化するためだと思います。 SSLEngineを一度だけインスタンス化してグローバル/静的変数にすると、アプリケーションレコードを正常にアンラップして、クライアントに応答を返すことができます。ページを更新したり、他のページを訪問したりすることができます。 sslハンドシェークプロセス全体をスキップしているので、ページの読み込みは非常に高速です。

残念ながら、これがすべて実行されている間に(IEやSafariなど)、別のブラウザからWebサーバーにアクセスした場合、SSLEngine内のセッション状態が不安定になり、Webサーバーは新しいSSL要求。 SSLEngineを一度インスタンス化し、グローバルにアクセス可能な静的変数にすることは実行可能な選択肢ではありません。だから...

2ページ目のリクエスト(ページリクエスト2)にどのように応答する必要がありますか? IPアドレス以外の最初のハンドシェイク要求(ページリクエスト#1)に2ページ目のリクエスト(ページリクエスト#2)を結びつける方法はありますか? 2番目のページリクエスト(ページリクエスト#2)のアプリケーションデータ内にSSLセッションIDが埋め込まれていますか?

ありがとうございました!

答えて

3

あなたはいない要求ごと、またはページごと、またはアプリケーションごとに、SocketChannelあたりの新しいSSLEngineをインスタンス化する必要があります。 SSLEngineは、一度に1つのSSL接続の状態しか把握していません。

+0

はい、もちろんです!メッセージが同じソケット接続を使用しているため、最初の要求に2番目の要求を結びつけることができます。私はそれを早期に考えなかったとは信じられません。再度EJPに感謝します! – Peter