Ich habe ein End-Entity-/Server-Zertifikat mit einem Zwischen- und einem Stammzertifikat. Wenn ich cat
auf das End-Entity-Zertifikat klicke, sehe ich nur ein einzelnes BEGIN
Tag END
. Es ist das einzige End-Entity-Zertifikat.
Gibt es eine Möglichkeit, den Inhalt des Zwischen- und Stammzertifikats anzuzeigen? Ich benötige nur den Inhalt BEGIN
und END
das Tag.
In Windows kann ich die vollständige Zertifikatskette im „Zertifizierungspfad“ sehen. Unten sehen Sie das Beispiel für das Stack Exchange-Zertifikat.
Von dort aus kann ich eineZertifikat ansehenund sie exportieren. Ich kann das sowohl für Root als auch für Zwischenbenutzer in Windows tun. Ich suche nach derselben Methode in Linux.
Antwort1
Von einer Website aus können Sie Folgendes tun:
openssl s_client -showcerts -verify 5 -connect stackexchange.com:443 < /dev/null
Dadurch werden die Zertifikatskette und alle vom Server vorgelegten Zertifikate angezeigt.
Wenn ich diese beiden Zertifikate jetzt in Dateien speichere, kann ich Folgendes verwenden 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
Die -untrusted
Option wird verwendet, um das/die Zwischenzertifikat(e) anzugeben; se.crt
ist das zu überprüfende Zertifikat. Das Ergebnis „Tiefe=2“ stammt aus dem vertrauenswürdigen CA-Speicher des Systems.
Wenn Sie die Zwischenzertifikate nicht haben, können Sie die Überprüfung nicht durchführen. So funktioniert X.509 nun einmal.
openssl x509 -in se.crt -noout -text
Je nach Zertifikat kann es eine URI enthalten, von der das Zwischenzertifikat abgerufen werden kann. Enthält beispielsweise :
Authority Information Access:
OCSP - URI:http://ocsp.digicert.com
CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt
Diese „CA Issuers“-URI verweist auf das Zwischenzertifikat (im DER-Format, Sie müssen openssl x509 -inform der -in DigiCertSHA2HighAssuranceServerCA.crt -out DigiCertSHA2HighAssuranceServerCA.pem
es also für die weitere Verwendung durch OpenSSL konvertieren).
Wenn Sie ausführen , openssl x509 -in /tmp/DigiCertSHA2HighAssuranceServerCA.pem -noout -issuer_hash
erhalten Sie 244b5494
, wonach Sie im Stamm-CA-Speicher des Systems unter suchen können /etc/ssl/certs/244b5494.0
(einfach .0
an den Namen anhängen).
Ich glaube nicht, dass es einen schönen, einfachen OpenSSL-Befehl gibt, der das alles für Sie erledigt.
Antwort2
tl;dr - Einzeiler-Bash-Magie, um alle Zertifikate in der Kette zu entleeren
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
Erklärung in 2 Schritten
Um alle Zertifikate in der Kette wie folgt in das aktuelle Verzeichnis zu übertragen 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}'
Der Bonustrack zur Umbenennung in ihre gebräuchlichen Namen:
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
Antwort3
Ich habe herausgefunden, dass -verify 5
OpenSSL mit der Option tief in die Kette eindringt und alle Zertifikate anzeigt, auch diejenigen, die nicht in Ihrer Zertifikatsbereitstellung enthalten sind.
Wenn Sie wirklich verstehen möchten, welche Kette mit Ihrem Zertifikat bereitgestellt wird, sollten Sie Folgendes ausführen:
openssl s_client -showcerts -partial_chain -connect YOUR_ENDPOINT:443 < /dev/null |less
Antwort4
Das oben genannte hat bei mir nicht funktioniert, als ich ein kostenloses Wildcard-Zertifikat von Lets Encrypt verwendet habe.
Genauer gesagt:
Ich habe einen Kubernetes-Cluster + Ingress-Controller, der mit einem kostenlosen Wildcard-Zertifikat von Lets Encrypt für *.mydomain.dev konfiguriert ist und die folgenden 2 Domänennamen hostet:
- grafana.meinedomain.dev
- prometheus.mydomain.dev
Ich musste das Flag -servername gemäß dieser Site wie folgt hinzufügen: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}'
Ich habe außerdem die Kette optimiert, sodass sie mir das vollständige Zertifikat + Zwischenzertifikat + Root für die Standardausgabe gibt und das Stderr-Rauschen ausblendet.
Tatsächlich ... habe ich beim Testen festgestellt, dass ich dadurch nicht die CA bekomme ...
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
Gibt einen anderen Wert zurück (und beim Testen einiger Dinge ist dies der Wert, der funktioniert.)