答案1
從網站上,您可以執行以下操作:
openssl s_client -showcerts -verify 5 -connect stackexchange.com:443 < /dev/null
這將顯示憑證鍊和伺服器提供的所有憑證。
現在,如果我將這兩個證書保存到文件中,我可以使用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
是要驗證的證書。深度=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 - 一個 liner 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 免費通配符憑證時,上述方法對我不起作用。
更具體地說:
我有一個 Kubernetes 叢集 + 入口控制器,它使用 *.mydomain.dev 的 Lets Encrypt 免費通配符憑證進行配置,它託管以下 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
給出不同的值(當測試某些東西時,這是有效的值。)