it-swarm.com.de

Überprüfen Sie eine Zertifikatskette mit openssl verify

Ich baue eine eigene Zertifikatskette mit folgenden Komponenten auf:
Root Certificate - Intermediate Certificate - User Certificate
Root-Zertifikat ist ein selbstsigniertes Zertifikat, Zwischenzertifikat wird von Root und Benutzer von Zwischenzertifikat signiert.

Jetzt möchte ich überprüfen, ob ein Benutzerzertifikat seinen Anker durch Stammzertifikat hat.

Mit
openssl verify -verbose -CAfile RootCert.pem Intermediate.pem
Die Validierung ist in Ordnung. Im nächsten Schritt validiere ich das Benutzerzertifikat mit
openssl verify -verbose -CAfile Intermediate.pem UserCert.pem
und die Überprüfung zeigt Fehler 20 bei 0-Tiefensuche an: Kann lokales Ausstellerzertifikat nicht abrufen

Was ist falsch?

107
Indra

In der 'Verify'-Dokumentation heißt es: "Wenn ein Zertifikat gefunden wird, bei dem es sich um seinen eigenen Aussteller handelt, wird davon ausgegangen, dass es sich um die Stammzertifizierungsstelle handelt." Mit anderen Worten, die Stammzertifizierungsstelle muss sich selbst signieren, damit die Überprüfung funktioniert. Aus diesem Grund hat Ihr zweiter Befehl nicht funktioniert.

Versuchen Sie dies stattdessen:

openssl verify -CAfile RootCert.pem -untrusted Intermediate.pem UserCert.pem

Es überprüft Ihre gesamte Kette mit einem einzigen Befehl.

126
Priyadi

Das ist einer der wenigen legitimen Jobs für cat:

openssl verify -verbose -CAfile <(cat Intermediate.pem RootCert.pem) UserCert.pem

Aktualisieren:

Wie Greg Smethells in den Kommentaren ausführt, vertraut dieser Befehl implizit Intermediate.pem . Ich empfehle, den ersten Teil der Post-Greg-Referenzen zu lesen (der zweite Teil befasst sich speziell mit pyOpenSSL und ist für diese Frage nicht relevant).

Für den Fall, dass der Beitrag wegfällt, zitiere ich die wichtigen Absätze:

Leider wird ein "Intermediate" -Zertifikat, das eigentlich ein root/self-signed ist wird als vertrauenswürdige Zertifizierungsstelle behandelt bei Verwendung des oben angegebenen empfohlenen Befehls:

$ openssl verify -CAfile <(cat geotrust_global_ca.pem rogue_ca.pem) fake_sometechcompany_from_rogue_ca.com.pem fake_sometechcompany_from_rogue_ca.com.pem: OK

Es scheint, dass openssl die Überprüfung der Kette beendet, sobald ein Stammzertifikat gefunden wird, das auch Intermediate.pem sein kann, wenn es selbst signiert ist. In diesem Fall wird RootCert.pem nicht berücksichtigt. Stellen Sie daher sicher, dass Intermediate.pem von einer vertrauenswürdigen Quelle stammt, bevor Sie sich auf den obigen Befehl verlassen.

40
Peter

Das Problem ist, dass openssl -verify Den Job nicht macht.

Wie von Priyadi erwähnt , openssl -verify Stoppt beim ersten selbstsignierten Zertifikat, daher verifizieren Sie die Kette nicht wirklich, da das Zwischenzertifikat oft selbstsigniert ist.

Ich gehe davon aus, dass Sie zu 101% sicher sein möchten, dass die Zertifikatdateien korrekt sind, bevor Sie versuchen, sie im produktiven Webdienst zu installieren. Dieses Rezept hier führt genau diesen Vorflug-Check durch.

Bitte beachte, dass die Antwort von Peter ist richtig , jedoch ist die Ausgabe von openssl -verify Kein Hinweis darauf, dass danach alles wirklich funktioniert. Ja, es könnte einige Probleme geben, aber nicht alle.

Hier ist ein Skript, das die Aufgabe hat, eine Zertifikatskette zu überprüfen, bevor Sie sie in Apache installieren. Vielleicht kann dies mit etwas mystischerer OpenSSL-Magie verbessert werden, aber ich bin kein OpenSSL-Guru und arbeite wie folgt:

#!/bin/bash
# This Works is placed under the terms of the Copyright Less License,
# see file COPYRIGHT.CLL.  USE AT OWN RISK, ABSOLUTELY NO WARRANTY. 
#
# COPYRIGHT.CLL can be found at http://permalink.de/tino/cll
# (CLL is CC0 as long as not covered by any Copyright)

OOPS() { echo "OOPS: $*" >&2; exit 23; }

PID=
kick() { [ -n "$PID" ] && kill "$PID" && sleep .2; PID=; }
trap 'kick' 0

serve()
{
kick
PID=
openssl s_server -key "$KEY" -cert "$CRT" "[email protected]" -www &
PID=$!
sleep .5    # give it time to startup
}

check()
{
while read -r line
do
    case "$line" in
    'Verify return code: 0 (ok)')   return 0;;
    'Verify return code: '*)    return 1;;
#   *)  echo "::: $line :::";;
    esac
done < <(echo | openssl s_client -verify 8 -CApath /etc/ssl/certs/)
OOPS "Something failed, verification output not found!"
return 2
}

ARG="${1%.}"
KEY="$ARG.key"
CRT="$ARG.crt"
BND="$ARG.bundle"

for a in "$KEY" "$CRT" "$BND"
do
    [ -s "$a" ] || OOPS "missing $a"
done

serve
check && echo "!!! =========> CA-Bundle is not needed! <========"
echo
serve -CAfile "$BND"
check
ret=$?
kick

echo
case $ret in
0)  echo "EVERYTHING OK"
    echo "SSLCertificateKeyFile $KEY"
    echo "SSLCertificateFile    $CRT"
    echo "SSLCACertificateFile  $BND"
    ;;
*)  echo "!!! =========> something is wrong, verification failed! <======== ($ret)";;
esac

exit $ret

Beachten Sie, dass die Ausgabe nach EVERYTHING OK Die Apache-Einstellung ist, da Benutzer von NginX oder haproxy dies normalerweise auch perfekt lesen und verstehen können;)

Es gibt ein GitHub Gist von diesem, das einige Updates haben könnte

Voraussetzungen für dieses Skript:

  • Sie haben die vertrauenswürdigen CA-Stammdaten wie gewohnt in /etc/ssl/certs, Zum Beispiel unter Ubuntu
  • Erstellen Sie ein Verzeichnis DIR, in dem Sie 3 Dateien speichern:
    • DIR/certificate.crt Welches das Zertifikat enthält
    • DIR/certificate.key Mit dem geheimen Schlüssel für Ihren Webservice (ohne Passphrase)
    • DIR/certificate.bundle Welches das CA-Bundle enthält. Informationen zum Vorbereiten des Bundles finden Sie weiter unten.
  • Führen Sie nun das Skript aus: ./check DIR/certificate (Dies setzt voraus, dass das Skript im aktuellen Verzeichnis den Namen check trägt)
  • Es ist sehr unwahrscheinlich, dass das Skript CA-Bundle is not needed Ausgibt. Dies bedeutet, dass Sie (lesen Sie: /etc/ssl/certs/) Dem Signaturzertifikat bereits vertrauen. Dies ist jedoch im WWW höchst unwahrscheinlich.
  • Für diesen Test muss Port 4433 auf Ihrer Workstation nicht verwendet werden. Und führen Sie dies besser nur in einer sicheren Umgebung aus, da Port 4433 in Kürze für die Öffentlichkeit geöffnet wird, wodurch in einer feindlichen Umgebung möglicherweise fremde Verbindungen hergestellt werden.

Wie erstelle ich die certificate.bundle - Datei?

Im WWW sieht die Vertrauenskette normalerweise so aus:

  • vertrauenswürdiges Zertifikat von /etc/ssl/certs
  • unbekannte (r) Zwischenzertifikat (e), möglicherweise von einer anderen Zertifizierungsstelle gegengezeichnet
  • ihr Zertifikat (certificate.crt)

Die Auswertung erfolgt nun von unten nach oben, das heißt, zuerst wird Ihr Zertifikat gelesen, dann wird das unbekannte Zwischenzertifikat benötigt, dann vielleicht das Quersignaturzertifikat und dann wird /etc/ssl/certs Zu Rate gezogen, um das zu finden richtiges vertrauenswürdiges Zertifikat.

Das ca-Bundle muss in genau der richtigen Bearbeitungsreihenfolge zusammengestellt werden, dh das erste benötigte Zertifikat (das Zwischenzertifikat, das Ihr Zertifikat signiert) steht im Bundle an erster Stelle. Dann wird das Cross-Signing-Zertifikat benötigt.

Normalerweise stellt Ihre Zertifizierungsstelle (die Behörde, die Ihr Zertifikat signiert hat) bereits eine solche richtige Ca-Bundle-Datei zur Verfügung. Wenn nicht, müssen Sie alle erforderlichen Zwischenzertifikate auswählen und sie zusammen in einer einzigen Datei (unter Unix) cat zusammenfassen. Unter Windows können Sie einfach einen Texteditor (wie notepad.exe) Öffnen und die Zertifikate in die Datei einfügen, wobei die ersten oben und die anderen folgen müssen.

Es gibt noch eine andere Sache. Die Dateien müssen im PEM-Format vorliegen. Einige Zertifizierungsstellen geben das DER-Format (ein Binärformat) aus. PEM ist leicht zu erkennen: Es ist ASCII lesbar. Weitere Informationen zum Konvertieren von Inhalten in PEM finden Sie unter Konvertieren von .crt in .pem und folgen Sie den gelben Anweisungen Kopfsteinpflasterstraße.

Beispiel:

Du hast:

  • intermediate2.crt Das Zwischenzertifikat, das Ihren certificate.crt
  • intermediate1.crt Ein weiteres Zwischenzertifikat, das intermediate2.crt
  • crossigned.crt Dies ist ein Kreuzsignaturzertifikat einer anderen Zertifizierungsstelle, die intermediate1.crt Signiert hat.
  • crossintermediate.crt Ist ein weiteres Zwischenprodukt der anderen Zertifizierungsstelle, die crossigned.crt Signiert hat (so etwas werden Sie wahrscheinlich niemals sehen).

Dann würde das richtige cat so aussehen:

cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle

Und wie können Sie herausfinden, welche Dateien in welcher Reihenfolge benötigt werden oder nicht?

Experimentieren Sie, bis das check Ihnen sagt, dass alles in Ordnung ist. Es ist wie ein Computer-Puzzle-Spiel, um das Rätsel zu lösen. Jeder. Single. Zeit. Auch für Profis. Aber Sie werden jedes Mal besser, wenn Sie dies tun müssen. Sie sind also definitiv nicht allein mit all diesen Schmerzen. Es ist SSL, weißt du? SSL ist wahrscheinlich eines der schlechtesten Designs, die ich je in über 30 Jahren professioneller Systemadministration gesehen habe. Überhaupt gewundert, warum Krypto in den letzten 30 Jahren nicht zum Mainstream geworden ist? Deshalb. 'nuff sagte.

13
Tino

Ich musste ein letsencrypt-Zertifikat überprüfen und habe es folgendermaßen gemacht:

  1. Laden Sie das Stammzertifikat und das Zwischenzertifikat aus der letsencrypt-Vertrauenskette herunter: https://letsencrypt.org/certificates/
  2. setze diesen Befehl ab:

openssl verify -CAfile letsencrypt-root-cert/isrgrootx1.pem.txt -untrusted letsencrypt-intermediate-cert/letsencryptauthorityx3.pem.txt /etc/letsencrypt/live/sitename.tld/cert.pem /etc/letsencrypt/live/sitename.tld/cert.pem: OK

Hoffe es hilft dir bei deinen Letsencrypt-Zertifikaten. Vielen Dank für Priyadi, Ihre Lösung hat mir geholfen, diesen Befehl zu finden. Bitte stelle sicher, dass du seine Lösung positiv bewertest.

5
Michael

Nachdem ich einen ganzen Tag mit genau demselben Problem verbracht hatte, ohne über SSL-Zertifikate informiert zu sein, lud ich CERTivity Keystores Manager herunter, importierte meinen Keystore und erhielt eine klare Visualisierung der Zertifikatskette .

Bildschirmfoto :

enter image description here

3