これは、「自己署名証明書とSSLEngine(JSSE)を使用したSSLハンドシェイク」のフォローアップ質問です。
同じポートでSSLメッセージと非SSLメッセージを処理できるNIOWebサーバーを実装しました。SSLメッセージと非SSLメッセージを区別するために、インバウンド要求の最初のバイトをチェックして、SSL/TLSメッセージであるかどうかを確認します。例:
byte a = read(buf);
if (totalBytesRead==1 && (a>19 && a<25)){
parseTLS(buf);
}
parseTLS()メソッドでは、SSLEngineをインスタンス化し、ハンドシェイクを開始し、メッセージをラップ/アンラップします。ほとんどの最新のWebブラウザー(Firefox 10、IE 9、Safari 5など)ではすべてが正常に機能しているようです。
問題は、IE6のような古いWebブラウザとJavaのURLConnectionクラスのようなライブラリがSSL/TLSハンドシェイクを異なる方法で開始するように見えることです。たとえば、IE 6の最初の数バイトは次のようになります(16進値)。
80 4F 01 03 00 ...
メッセージをSSLEngineに渡すと、メッセージを認識していないようで、例外がスローされます。
javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
では、IE 6とJavaのURLConnectionクラスは正確には何を送信しているのでしょうか?これは、JSSESSLEngineがサポートできる有効なSSL/ TLSメッセージですか?別のメッセージを送信するには、前処理を行う必要がありますか、それともクライアントと交渉する必要がありますか?
前もって感謝します!
アップデート
ブルーノとEJP、そしてさらにいくつかのデバッグのおかげで、私は何が起こっているのかをはるかによく理解できました。ブルーノが正しく指摘したように、IE6およびJava6クライアントはSSLv2ClientHelloを介して送信しています。以前のコメントの1つとは異なり、Java 1.6のSSLEngineは、実際にはSSLv2メッセージをアンラップし、クライアントに送り返すための有効な応答を生成できます。以前に報告したSSLExceptionは私の側のエラーであり、SSLEngineとは関係ありません(クライアントがデータの送信を完了したと誤って想定し、SSLEngineがより多くのデータのラップ解除を期待していたときに空のByteBufferになってしまいました)。