そのため、ここ数日、Tomcat6/Camel/Cxf から IIS6 への双方向 SSL セットアップに取り組んできました。
簡単な概要: Tomcat の Camel で実行されている cxf コンシューマーがあり、IIS でサード パーティがホストする Web サービスを呼び出します。サードパーティは「有効な」証明書を使用していますが、私たちは自己署名証明書を使用しています。IIS は、クライアント認証を要求するように構成されています。
cxf が正しく設定され、相互認証が実行されるところまで来ました。
そこにたどり着くために修正する必要があったいくつかの落とし穴:
- allowUnsafeRenegotiation=true
- https.protocols=TLSv1 (それ以外の場合、Java はハンドシェイクの途中で SSLv2 クライアントの hello を送信します)
- ほとんどの CXF の例からコピーしたデフォルトの暗号スイート フィルターを削除します。厳しすぎました
curl を使用してサードパーティへの呼び出しを行うことができ、有効な SOAP 応答が返されるため、すべての証明書、ファイアウォール設定などは正しいです。
問題:アプリケーションから SOAP POST メッセージを送信すると、タイムアウト例外が発生します。
ssl デバッグ ログを調べると、奇妙なエラーがいくつかあります (不要なものをすべて削除しようとしました)。
trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: true
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
http-9203-1, setSoTimeout(120000) called
%% No cached client session
*** ClientHello, TLSv1
http-9203-1, WRITE: TLSv1 Handshake, length = 111
http-9203-1, READ: TLSv1 Handshake, length = 2454
*** ServerHello, TLSv1
RandomCookie: GMT: 1354816328 bytes = { 63, 194, 181, 182, 56, 251, 234, 198, 234, 92, 162, 175, 243, 127, 133, 182, 0, 237, 102, 9, 37, 133, 141, 3, 175, 120, 34, 92 }
Session ID: {36, 10, 0, 0, 166, 131, 36, 81, 251, 181, 83, 154, 76, 240, 235, 82, 39, 135, 239, 235, 231, 195, 17, 225, 220, 59, 105, 207, 116, 185, 114, 172}
Cipher Suite: SSL_RSA_WITH_RC4_128_MD5
Compression Method: 0
***
Warning: No renegotiation indication extension in ServerHello
%% Created: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
** SSL_RSA_WITH_RC4_128_MD5
*** Certificate chain
***
Found trusted certificate:
*** ServerHelloDone
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
http-9203-1, WRITE: TLSv1 Handshake, length = 262
http-9203-1, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data: { 124, 172, 175, 239, 103, 187, 134, 164, 206, 241, 145, 41 }
***
http-9203-1, WRITE: TLSv1 Handshake, length = 32
http-9203-1, READ: TLSv1 Change Cipher Spec, length = 1
http-9203-1, READ: TLSv1 Handshake, length = 32
*** Finished
verify_data: { 84, 207, 104, 255, 19, 151, 27, 11, 159, 84, 124, 216 }
***
%% Cached client session: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
[read] MD5 and SHA1 hashes: len = 16
0000: 14 00 00 0C 54 CF 68 FF 13 97 1B 0B 9F 54 7C D8 ....T.h......T..
Padded plaintext before ENCRYPTION: len = 365
0000: 50 4F 53 54 20 2F 69 73 61 2E 64 6C 6C 2F 41 43 POST /isa.dll/AC
http-9203-1, WRITE: TLSv1 Application Data, length = 365
Padded plaintext before ENCRYPTION: len = 1200
0000: 3C 73 6F 61 70 3A 45 6E 76 65 6C 6F 70 65 20 78 <soap:Envelope x
http-9203-1, WRITE: TLSv1 Application Data, length = 1200
default-workqueue-1, READ: TLSv1 Handshake, length = 20
これは、クライアント認証なしの最初のハンドシェイクです (IIS は再ネゴシエーションを使用してクライアント証明書を取得しているため)。SOAP メッセージを送信する最初の試行は既に行われていることに注意してください (これは正常ですか?)。
Allow unsafe renegotiation: true
Allow legacy hello messages: true
Is initial handshake: false
Is secure renegotiation: false
*** HelloRequest (empty)
Warning: continue with insecure renegotiation
%% Client cached [Session-1, SSL_RSA_WITH_RC4_128_MD5]
%% Try resuming [Session-1, SSL_RSA_WITH_RC4_128_MD5] from port 58460
*** ClientHello, TLSv1
default-workqueue-1, WRITE: TLSv1 Handshake, length = 159
default-workqueue-1, READ: TLSv1 Handshake, length = 5416
*** ServerHello, TLSv1
%% Created: [Session-2, SSL_RSA_WITH_RC4_128_MD5]
** SSL_RSA_WITH_RC4_128_MD5
*** Certificate chain
***
Found trusted certificate:
*** CertificateRequest
*** ServerHelloDone
matching alias: servercert
*** Certificate chain
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
default-workqueue-1, WRITE: TLSv1 Handshake, length = 909
*** CertificateVerify
default-workqueue-1, WRITE: TLSv1 Handshake, length = 150
[Raw write]: length = 155
default-workqueue-1, WRITE: TLSv1 Change Cipher Spec, length = 17
*** Finished
verify_data: { 242, 160, 100, 95, 172, 14, 166, 71, 158, 148, 220, 42 }
***
default-workqueue-1, WRITE: TLSv1 Handshake, length = 32
default-workqueue-1, READ: TLSv1 Change Cipher Spec, length = 17
default-workqueue-1, READ: TLSv1 Handshake, length = 32
*** Finished
verify_data: { 115, 32, 183, 236, 113, 63, 144, 117, 126, 132, 150, 67 }
***
%% Cached client session: [Session-2, SSL_RSA_WITH_RC4_128_MD5]
default-workqueue-1, handling exception: java.net.SocketException: Connection reset
%% Invalidated: [Session-2, SSL_RSA_WITH_RC4_128_MD5]
default-workqueue-1, SEND TLSv1 ALERT: fatal, description = unexpected_message
default-workqueue-1, WRITE: TLSv1 Alert, length = 18
default-workqueue-1, Exception sending alert: java.net.SocketException: Broken pipe
default-workqueue-1, called closeSocket()
default-workqueue-1, called close()
default-workqueue-1, called closeInternal(true)
2 番目のハンドシェイクは、クライアント証明書をサーバーに送信します。詳細なログを削除しましたが、証明書が見つかり、OK されました。ご覧のとおり、このハンドシェイクは既にエラーで終了しています (時間の遅延はありません)。
Allow unsafe renegotiation: true
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
default-workqueue-1, setSoTimeout(120000) called
%% No cached client session
*** ClientHello, TLSv1
default-workqueue-1, WRITE: TLSv1 Handshake, length = 111
default-workqueue-1, READ: TLSv1 Handshake, length = 2454
*** ServerHello, TLSv1
Warning: No renegotiation indication extension in ServerHello
%% Created: [Session-3, SSL_RSA_WITH_RC4_128_MD5]
** SSL_RSA_WITH_RC4_128_MD5
***
Found trusted certificate:
*** ServerHelloDone
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
default-workqueue-1, WRITE: TLSv1 Handshake, length = 262
... no IV used for this cipher
default-workqueue-1, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data: { 130, 65, 225, 31, 41, 14, 21, 42, 102, 176, 151, 245 }
***
default-workqueue-1, WRITE: TLSv1 Handshake, length = 32
default-workqueue-1, READ: TLSv1 Change Cipher Spec, length = 1
default-workqueue-1, READ: TLSv1 Handshake, length = 32
*** Finished
verify_data: { 125, 78, 165, 103, 115, 60, 111, 169, 180, 174, 0, 169 }
***
%% Cached client session: [Session-3, SSL_RSA_WITH_RC4_128_MD5]
default-workqueue-1, WRITE: TLSv1 Application Data, length = 365
default-workqueue-1, handling exception: java.net.SocketTimeoutException: Read timed out
default-workqueue-1, called close()
default-workqueue-1, called closeInternal(true)
default-workqueue-1, SEND TLSv1 ALERT: warning, description = close_notify
default-workqueue-1, WRITE: TLSv1 Alert, length = 18
次に、3 回目のハンドシェイクが実行され (通常?)、再び SOAP メッセージの POST が実行されます (アプリケーションの日付の書き込み)。その後、ソケットのタイムアウトが期限切れになるまでログが待機します (2 分または 10 秒に設定しましたが、違いはありません)。その後、SocketTimeoutException が発生します。SSLv3 または 2 に切り替えてみましたが、まったく同じ結果が得られます。
この動作の原因は何ですか?