NIO と SSLEngine を使用して SSL Web サーバーに取り組んでいます。ハンドシェイクを正常に処理し、アプリケーション データを送受信できます。ただし、SSL セッション状態を維持する方法を理解するのに苦労しています。
Web サーバーのテストに Firefox 10 を使用しています。最初のページの読み込みでは、すべてがうまく機能します。ハンドシェークが正常に完了しました。サーバーはクライアントの要求を処理し、応答を返します。レスポンスは問題なく送信され、ブラウザはアプリケーション データ (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 を 1 回だけインスタンス化してグローバル/静的変数にすると、アプリケーション レコードが正常にラップ解除され、クライアントに応答を返すことができます。問題なくページを更新したり、他のページにアクセスしたりできます。SSL ハンドシェイク プロセス全体をスキップしているため、ページの読み込みは非常に高速です。
残念ながら、これらすべての処理中に別のブラウザー (IE や Safari など) から Web サーバーにアクセスすると、SSLEngine 内のセッション状態が不安定になり、Web サーバーは新しい SSL 要求に応答できなくなります。そのため、SSLEngine を一度インスタンス化して、それをグローバルにアクセス可能な静的変数にすることは、実行可能なオプションではないようです。そう...
2 番目のページ リクエスト (ページ リクエスト #2) には、一体どのように応答すればよいのでしょうか? IP アドレス以外で、2 番目のページ要求 (ページ要求 #2) を最初のハンドシェイク要求 (ページ要求 #1) に結び付ける方法はありますか? 2 番目のページ要求 (ページ要求 #2) のアプリケーション データ内に SSL セッション ID が埋め込まれていますか?
前もって感謝します!