1. ホーム
  2. ssl

[解決済み] openssl s_client -cert: クライアント証明書がサーバーに送信されたことを証明する

2022-03-03 11:55:38

質問

背景

SSLサーバで保護されたAPIを持つサービスプロバイダと指をくわえて見ているしかない状態です とクライアント 証明書を発行しています。

  • CSRを生成し、パブリックCA(この場合はGoDaddy)から証明書を取得し、サービスプロバイダーに証明書とCAチェーンを提供しました。
  • 彼らは、CAと私のクライアント証明書をゲートウェイに読み込んだと思われます。
  • を使用した最も基本的なレベルのテストに取り組んでいます。 openssl s_client -connect ... -cert ... -key ...
  • プロバイダから、私のリクエストにクライアント SSL 証明書が全く含まれていないことを示すログがあると言われた。
  • 不思議なことに、私の証明書の適切なCA発行者は、SSLハンドシェイク中に提供される"Acceptable client certificate CA names"のリストに表示されています。
  • 参考までに、私が作成し、テスト用に提供した自己署名入り証明書は、実際に正しく機能します。

リクエストの例(失敗

[shell ~]$ openssl s_client -connect host:443 -cert cert_and_key.pem -key cert_and_key.pem -state -quiet
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 **SNIP**
verify return:1
depth=1 **SNIP**
verify return:1
depth=0 **SNIP**
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write certificate verify A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL3 alert read:fatal:unknown CA
SSL_connect:failed in SSLv3 read finished A
140011313276744:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1197:SSL alert number 48
140011313276744:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:

私の読みでは SSL3 alert read:fatal:unknown CA のエラーは、私が(実際には)提供している証明書の発行者をサーバーが認識していないためです。しかし、プロバイダーはCA証明書が適切にロードされていると私に保証しており、私はそうでないことを納得させることができませんでした。

質問事項

そこで、他の(広範囲にわたる)トラブルシューティングの手順はさておき、私が本当に知りたいことは。

からの出力はありますか? openssl s_client クライアント証明書が単にサーバーに要求されただけでなく、実際には 送信 は、SSLハンドシェイク中にサーバーに送信するのですか?

を実験してみました。 -state , -msg , -debug-trace というオプションがありますが、その出力を解釈するのに必要なバックグラウンドを持っていません。

EJPの回答では、私が提供したサンプル出力では、十分な証明になるように write client certificate A の有無にかかわらず出力されます。 -cert オプションが使用されているかどうかを示しているわけではありません。 送信 .

解決方法は?

クライアント証明書がサーバーに送信されていることを確認するためには、クライアント証明書との組み合わせによる出力を分析する必要があります。 -state-debug フラグを使用します。

まず、ベースラインとして、以下を実行してみてください。

$ openssl s_client -connect host:443 -state -debug

たくさんの出力が得られますが、私たちが関心を持つ行は次のようなものです。

SSL_connect:SSLv3 read server done A
write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
0000 - 16 03 01 00 07 0b 00 00-03                        .........
000c - <SPACES/NULS>
SSL_connect:SSLv3 write client certificate A

ここで起きていること

  • -state フラグは、前のセクションの終わりを表示する役割を担っています。

    SSL_connect:SSLv3 read server done A  
    
    

    これは、出力の中で自分の居場所を見つけるためにのみ重要です。

  • 次に -debug フラグは、次のステップで送信される生バイトを示しています。

    write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
    0000 - 16 03 01 00 07 0b 00 00-03                        .........
    000c - <SPACES/NULS>
    
    
  • 最後に -state フラグは、再びステップの結果を報告しています。 -debug がエコーされたところです。

    SSL_connect:SSLv3 write client certificate A
    
    

つまり、言い換えれば s_client は、サーバーから送られてきたデータの読み取りを終了し、12バイトをサーバーに送信する(と思われる)。 クライアント証明書がありません。 というメッセージが表示されます。


このテストを繰り返すと、今度は -cert-key のフラグはこのようになります。

$ openssl s_client -connect host:443 \
   -cert cert_and_key.pem \
   -key cert_and_key.pem  \
   -state -debug

の間に出力されます。 "読み取りサーバーが完了しました"。 という行と "クライアント証明書を書き込む" の行はもっと長くなり、クライアント証明書のバイナリ形式を表します。

SSL_connect:SSLv3 read server done A
write to 0x7bd970 [0x86d890] (1576 bytes => 1576 (0x628))
0000 - 16 03 01 06 23 0b 00 06-1f 00 06 1c 00 06 19 31   ....#..........1
(*SNIP*)
0620 - 95 ca 5e f4 2f 6c 43 11-                          ..^%/lC.
SSL_connect:SSLv3 write client certificate A

1576 bytes は、それだけで証明書が送信されたことを示す優れたものですが、その上、右側の列には人間が読める証明書の部分が表示されます。この中に、あなたの証明書のCNと発行者の文字列があることがわかるはずです。