新しいCA証明書がクライアントにプッシュされるときに、証明書チェーンをダウンロードしてローカルで検証しようとしています。基本的に、どのサイトがいつでも機能するかどうかを確認しています。次のコマンドを使用してチェーンをダウンロードします。
echo -n | openssl s_client -showcerts -connect example.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mycert.pem
ただし、openssl verify
エラーメッセージが表示されます。
root@Host:~# openssl version
OpenSSL 1.1.0e 16 Feb 2017
root@Host:~# echo -n | openssl s_client -showcerts -connect example.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mycert.pem
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify return:1
depth=0 C = US, ST = California, L = Los Angeles, O = Internet Corporation for Assigned Names and Numbers, OU = Technology, CN = www.example.org
verify return:1
DONE
root@Host:~# openssl verify mycert.pem
C = US, ST = California, L = Los Angeles, O = Internet Corporation for Assigned Names and Numbers, OU = Technology, CN = www.example.org
error 20 at 0 depth lookup: unable to get local issuer certificate
error mycert.pem: verification failed
このような証明書チェーンをオフラインで検証する正しい方法は何ですか?
だから私はこれに対する答えを見つけました、OpenSSLはファイル内の最初の証明書のみを検証します。つまり、有効なチェーンがある場合は、最後の証明書のみを検証する必要があります。
検証する証明書を1つのファイルに入れ、チェーンを別のファイルに入れます。
openssl verify -CAfile chain.pem mycert.pem
(もちろん)openssl
がchain.pemに含まれていない場合にルート証明書を見つける方法を知っていることも重要です。これを行う必要がある場合(独自のCAを使用している場合)、代わりのディレクトリを指定して、-CApath
で検索することもできます。
問題は-showcerts
コマンドの出力にあります。証明書とそれに署名した証明書のみがあり、おそらく中間証明書であり、完全なチェーンではありません。 OKステートメントを使用するには、次のことを行う必要があります。
-BEGIN END-
ブロック)をファイルmycert.crt
に入れますCAcerts.crt
に入れますopenssh -text -in CAcerts.crt
で確認して、これに署名したルートCAを探し、CAfile.crt
に追加します。openssl verify -CAfile CAcerts.crt mycert.crt
注:設定GUI(証明書を表示してエクスポート)を使用するか、Firefoxプロファイルディレクトリにあるcertutil
を使用してコマンドラインでFirefoxストアから既知のCA証明書を取得できます。例えば:
$ find $HOME/.mozilla/firefox -name cert8.db # point for example to abcdef.default directory
$ certutil -a -L -d $HOME/.mozilla/firefox/abcdef.default/ -n "Let's Encrypt` Authority X3"
certtool
とopenssl
を組み合わせることで、目的の結果を得ることができます。ここで重要なことは2つあります。1つはチェーン自体を検証すること、もう1つはローカルにインストールされた信頼されたルート証明書に対してチェーンが信頼されているかどうかをチェックすることです。
否定的なケースをチェックしてください。つまり、テストが無効としてピックアップする必要があるものが正しく無効としてピックアップされることを確認してください。 https://badssl.com/ または自分で作成したものでそれを行うことができます。ネガティブケースがテスト中のあらゆるもので失敗することが確実にわからない場合、テストはあまり役に立ちません。
チェーンが信頼できることを確認するには:
openssl s_client -showcerts -connect example.com:443 </dev/null 2>/dev/null \
| sed -ne '/-BEGIN/,/-END/p' \
| certtool --verify
チェーンの整合性のみを検証する-信頼はしない:
openssl s_client -showcerts -connect example.com:443 </dev/null 2>/dev/null \
| sed -ne '/-BEGIN/,/-END/p' \
| certtool --verify-chain
信頼できるチェーンの例:
$ openssl s_client -showcerts -connect example.com:443 </dev/null 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' | certtool --verify
Loaded system trust (154 CAs available)
Subject: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Issuer: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Subject: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Issuer: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Subject: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Issuer: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
Checked against: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
Signature algorithm: RSA-SHA256
Output: Verified. The certificate is trusted.
Subject: CN=www.example.org,OU=Technology,O=Internet Corporation for Assigned Names and Numbers,L=Los Angeles,ST=California,C=US
Issuer: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Checked against: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Signature algorithm: RSA-SHA256
Output: Verified. The certificate is trusted.
Chain verification output: Verified. The certificate is trusted.
信頼できないチェーンの例:
$ openssl s_client -showcerts -connect untrusted-root.badssl.com:443 </dev/null 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' | certtool --verify
Loaded system trust (154 CAs available)
Subject: CN=*.badssl.com,O=BadSSL,L=San Francisco,ST=California,C=US
Issuer: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Subject: CN=*.badssl.com,O=BadSSL,L=San Francisco,ST=California,C=US
Issuer: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Subject: CN=*.badssl.com,O=BadSSL,L=San Francisco,ST=California,C=US
Issuer: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Chain verification output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
それでも信頼されていないチェーンが有効かどうかを確認する:
$ openssl s_client -showcerts -connect untrusted-root.badssl.com:443 </dev/null 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' | certtool --verify-chain
Subject: CN=*.badssl.com,O=BadSSL,L=San Francisco,ST=California,C=US
Issuer: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Checked against: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Signature algorithm: RSA-SHA256
Output: Verified. The certificate is trusted.
Chain verification output: Verified. The certificate is trusted.