中間証明書とルート証明書を持つエンド エンティティ/サーバー証明書があります。cat
エンド エンティティ証明書を開くと、単一のタグのみが表示されますBEGIN
。END
これは唯一のエンド エンティティ証明書です。
BEGIN
中間証明書とルート証明書の内容を表示する方法はありますか。必要なのは、とタグの内容だけですEND
。
Windows では、「証明パス」から完全な証明書チェーンを確認できます。以下は Stack Exchange の証明書の例です。
そこから私はビューの証明書エクスポートします。Windows ではルートと中間の両方でこれを行うことができます。Linux でも同じ方法を探しています。
答え1
Web サイトからは、次の操作を実行できます。
openssl s_client -showcerts -verify 5 -connect stackexchange.com:443 < /dev/null
これにより、証明書チェーンとサーバーが提示したすべての証明書が表示されます。
さて、これら 2 つの証明書をファイルに保存すると、次を使用できますopenssl verify
。
$ openssl verify -show_chain -untrusted dc-sha2.crt se.crt
se.crt: OK
Chain:
depth=0: C = US, ST = NY, L = New York, O = "Stack Exchange, Inc.", CN = *.stackexchange.com (untrusted)
depth=1: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA (untrusted)
depth=2: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
この-untrusted
オプションは中間証明書を指定するために使用されます。これse.crt
は検証する証明書です。depth=2 の結果は、システムの信頼された CA ストアから取得されました。
中間証明書がない場合、検証は実行できません。これが X.509 の仕組みです。
証明書によっては、中間証明書を取得するための URI が含まれている場合があります。例として、次のものopenssl x509 -in se.crt -noout -text
が含まれます。
Authority Information Access:
OCSP - URI:http://ocsp.digicert.com
CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt
この「CA Issuers」URI は中間証明書を指します (DER 形式なので、openssl x509 -inform der -in DigiCertSHA2HighAssuranceServerCA.crt -out DigiCertSHA2HighAssuranceServerCA.pem
OpenSSL でさらに使用できるように変換する必要があります)。
を実行するとopenssl x509 -in /tmp/DigiCertSHA2HighAssuranceServerCA.pem -noout -issuer_hash
が取得され244b5494
、これは のシステム ルート CA ストアで検索できます/etc/ssl/certs/244b5494.0
(.0
名前に追加するだけです)。
これらすべてを実行する、便利で簡単な OpenSSL コマンドは存在しないと思います。
答え2
tl;dr - チェーン内のすべての証明書をダンプするワンライナーの bash マジック
openssl s_client -showcerts -verify 5 -connect wikipedia.org:443 < /dev/null |
awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
for cert in *.pem; do
newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
echo "${newname}"; mv "${cert}" "${newname}"
done
2ステップで説明
チェーン内のすべての証明書を現在のディレクトリにダンプするには、次のようにしますcert${chain_number}.pem
。
openssl s_client -showcerts -verify 5 -connect your_host:443 < /dev/null |
awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
一般的な名前に変更するためのボーナストラック:
for cert in *.pem; do
newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
mv $cert $newname
done
答え3
-verify 5
オプションを使用すると、openssl はチェーンの奥深くまで移動し、証明書の展開に含まれていないものも含め、すべての証明書を表示することがわかりました。
証明書にどのチェーンが提供されているかを本当に理解したい場合は、次のコマンドを実行する必要があります。
openssl s_client -showcerts -partial_chain -connect YOUR_ENDPOINT:443 < /dev/null |less
答え4
上記の方法は、Lets Encrypt の無料ワイルドカード証明書を使用していたときには機能しませんでした。
具体的には、
*.mydomain.dev の Lets Encrypt の無料ワイルドカード証明書を使用して構成された Kubernetes クラスター + Ingress コントローラーがあり、次の 2 つのドメイン名をホストしています。
- grafana.mydomain.dev
- prometheus.mydomain.dev
このサイトに従って、次の -servername フラグを追加する必要がありました。https://community.letsencrypt.org/t/where-can-i-download-the-trusted-root-ca-certificates-for-lets-encrypt/33241/2
export DOMAIN=grafana.mydomain.dev
openssl s_client -showcerts -verify 5 -connect $DOMAIN:443 -servername $DOMAIN < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'
また、チェーンを微調整して、完全な証明書 + 中間証明書 + ルート証明書を標準出力に提供し、stderr ノイズを非表示にしました。
実は... テストしてみると、これでは CA が得られないことがわかりました...
openssl s_client -showcerts -verify 5 -connect letsencrypt.org:443 < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'
curl https://letsencrypt.org/certs/isrgrootx1.pem
異なる値を与えます (いくつかのものをテストする場合、これが機能する値です)。