web-dev-qa-db-ja.com

SSL相互認証が失敗する

サーバーとクライアント間の相互認証を確立しようとすると、以下のエラーが発生します。

サーバーとクライアント間のタイミングはまったく同じで、証明書はサーバーとクライアントで適切です。このエラーの原因は何ですか?このエラーが発生する可能性のある方法は何ですか?

  Thread-10, WRITE: TLSv1 Change Cipher Spec, length = 1
[Raw write]: length = 6
0000: 14 03 01 00 01 01                                  ......
*** Finished
verify_data:  { 130, 243, 38, 76, 253, 223, 88, 181, 223, 28, 110, 123 }
***
[write] MD5 and SHA1 hashes:  len = 16
0000: 14 00 00 0C 82 F3 26 4C   FD DF 58 B5 DF 1C 6E 7B  ......&L..X...n.
Padded plaintext before ENCRYPTION:  len = 48
0000: 14 00 00 0C 82 F3 26 4C   FD DF 58 B5 DF 1C 6E 7B  ......&L..X...n.
0010: F5 44 95 0D 5A D0 8E 6F   40 89 10 2D 00 5F BB CF  [email protected]._..
0020: 30 D1 C6 06 0B 0B 0B 0B   0B 0B 0B 0B 0B 0B 0B 0B  0...............
Thread-8, WRITE: TLSv1 Handshake, length = 48
Thread-8, waiting for close_notify or alert: state 1
[Raw read]: length = 5
0000: 15 03 01 00 02                                     .....
[Raw read]: length = 2
0000: 02 2E                                              ..
Thread-8, READ: TLSv1 Alert, length = 2
Thread-8, RECV TLSv1 ALERT:  fatal, certificate_unknown
%% Invalidated:  [Session-4, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
Thread-8, called closeSocket()
Thread-8, Exception while waiting for close javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
Thread-8, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
Thread-8, called close()
Thread-8, called closeInternal(true)

あなたの助けは大歓迎です。

4
user45475

まあ、あなたは言う:

証明書はサーバーとクライアントで適切です

しかし、少なくとも1つのシステムは同意しません。

Received fatal alert: certificate_unknown

このメッセージは、1つのパーティ(クライアント側のログとサーバー側のログのどちらを表示しているかはわかりません)が、クラス「fatal」と値46(0x2E、別名「certificate_unknown」)の明示的なアラートメッセージをサーバーから受信したことを意味します。 TLS 1.0標準 で指定されているとおり:

certificate_unknown
    Some other (unspecified) issue arose in processing the
    certificate, rendering it unacceptable.

「その他」とは、証明書の期限切れや失効、サポートされていない暗号アルゴリズムの使用の問題ではないことを意味します。受信した証明書が「受け入れられない」ことには多くの原因が考えられますが、その主な原因は、先験的な既知の信頼されたルートから有効なチェーンを構築できないことです。証明書自体までのCA(通常、その場合、システムは「unknown_ca」アラートを送信する必要がありますが、多くの場合、証明書のエラーを報告する精度が高くありません)。

問題をさらに調査するには、次のことを行う必要があります。

  • クライアントとサーバーの両方で完全ロギングをアクティブ化します。警告メッセージを受信したシステムからのログを表示します。他のシステムからのログを見て、誰がsentアラートメッセージを送信したかを確認する必要があります。

  • 特に、アラートメッセージを送信したシステム(「致命的なアラートを受信した」例外をスローしたシステムではなく、他のシステム)の両方のシステムの構成を確認してください。ピアの証明書の検証に使用している信頼アンカー。

  • システムが実際に送信している証明書チェーンを確認します。これは暗号化がアクティブになる前に発生するため、証明書はいくつかのネットワーク監視ツールà Wireshark に表示されるはずです。特に、orderを確認してください:SSL/TLSでは、エンドエンティティ証明書が最初に来て、次にそれを発行したCA、次にそれを発行したCA CAなど。

クライアント証明書はauthenticationではなくauthorizationとしてではなく、 。信頼されたルートに関してサーバーが検証できる証明書をクライアントが送信した場合でも、これはサーバーwhoの反対側にのみ通知しますこの線。特定のクライアントに処理を許可するかどうかは、サーバーが決定します。これは通常、クライアント証明書をアイデンティティまたはロールにマッピングすることを伴います。証明書から特定のフィールドを抽出する。このプロセスは完全にTLS自体の範囲外ですが、それでも発生する必要があるため、サーバー側にいくつかのソフトウェアと、決定的にはいくつかの構成がありますおそらく確認したいことです。

他の方向(クライアントによるサーバーの証明書の検証)では、ルールは RFC 2818 で、少なくともHTTPSのコンテキストで指定されます:対象サーバーname(ターゲットURLから抽出されたもの)は、サーバーの証明書に表示されます。 HTTPSの外では、サーバーから取得した証明書が正しいかどうか、つまり証明書がvalidであるかどうかを判断するのは、各クライアントアプリケーションの責任です。 (信頼されたCAなどによって適切に発行されます)、ただし、識別されたサーバーが実際にクライアントが通信するサーバーであることも必要です。再び、構成。

5
Tom Leek