X.509-Zertifikate
Nichts scheint ominöser zu sein als der Umgang mit Zertifikaten. Ich erlebe im täglichen Umgang mit Zertifikaten, dass zu viele Administratoren daran verzweifeln, dabei sind Zertifikate sehr einfach aufgebaut und folgen einer simplen Struktur.
Ich möchte in dem Artikel nicht auf jedes Detail eingehen, es gibt auch Ecken an denen man berechtigterweise Verzweifelt. Den Bereich möchte ich mir und euch in diesem Beitrag ersparen. Der folgende Rundumschlag sollte aber jedem den Umgang mit X.509 Zertifikaten verdeutlichen und ein zwei Tipps mit auf den Weg geben, die den Umgang erleichtern und die Implementierung etwas sicherer gestalten können.
Vertrauensstellung
Jeder kann ein eigenes Zertifikat erstellen (self-signed) und damit seine Kommunikation absichern, dass Problem ist, das andere per se nicht Wissen, ob das übermittelte Zertifikat auch vertrauenswürdig ist, es kann ja schließlich jeder eines erstellen. Browser, zum Beispiel, werfen bei einem self-signed Zertifikat eine Warnung und fordern den Benutzer auf das Zertifikat selbst zu prüfen, da es zunächst nicht vertrauenswürdig scheint. Wenn man sich dennoch verbinden möchte, muss man zunächst akzeptieren das man eine scheinbar nicht vertrauenswürdigen Verbindung herstellt. Bei einer handvoll Benutzern ist ein self-signed Zertifikat noch via Telefon, Mail oder Messenger zu kommunizieren und somit ein echtes Vertrauen herzustellen. In einer Firma kann man solche Zertifikate zentral hinterlegen und somit zur Gültigkeit innerhalb der eigenen Infrastruktur verhelfen. Hat man allerdings viele unbekannten Benutzern, wie bei einer Webseite, ist so eine Vertrauensstellung nicht mehr zu realisieren.
An diesem Punkt springen Dritte für uns in die Presche, die sogenannten Certifcate Authoritys (CA). CAs sind Firmen die auch mit einem selbst erstellen Zertifikat (self-signed) arbeiten, diese Zertifikate werden allerdings in allen gängigen Applikationen und Betriebssystemen als Vertrauenswürdig hinterlegt (CA-Liste). Diese von CAs eingesetzten Zertifikaten werden als CA-Root-Zertifikat bezeichnet. Egal welches Zertifikat solch ein CA erzeugt, beruhend auf dem CA-Root-Zertifikat, wird das Zertifikat per se als Vertrauenswürdig eingestuft. Die CAs erhalten die Vertrauenswürdigkeit auf der Grundlage von Prüfungen, wenn sie diese nicht erfüllen, werden sie in der Regel aus den CA-Listen entfernt und alle darauf basierenden Zertifikate verlieren ihre Gültigkeit
Wie wird Vertrauen hergestellt
Wie oben erwähnt, hat jeder CA mindestens ein CA-Root-Zertifikat und kann von diesem Zertifikat ein neues Zertifikat ableiten. Das abgeleitete Zertifikat verweist letztlich immer auf das vertraute CA-Root-Zertifikat und wird dadurch Vertrauenswürdig. Das CA-Root-Zertifikat bürgt immer für das abgeleitete Zertifikat. Jede Applikation prüft also ein Zertifikat auf sein CA-Root-Zertifikat.
Es muss natürlich auch möglich sein, bestehende Zertifikate wieder das Vertrauen zu entziehen. Es gibt zum einen die Möglichkeit die Laufzeit eines Zertifikates zu begrenzen, was die Regel ist, zum anderen gibt es bei jedem CA eine Liste, wo seine widerrufende Zertifikate aufgelistet sind. Welche Adresse das ist, ist ebenfalls im Zertifikat hinterlegt. Die Listen werden typischerweise über das OCSP (Online Certificate Status Protocol) abgefragt, dort können die Applikationen sich nochmals versichern, dass das Zertifikat noch seine Gültigkeit hat und nicht zurück gezogen wurde.
Aufbau eines X.509 Zertifikates
Jedes Zertifikat besteht aus einem privaten geheimen Zertifikatsschlüssel (KEY) und einem öffentlichem Zertifikat (CRT). Das öffentliche Zertifikat wird jedem Benutzer vorgelegt, damit dieser entscheiden kann, ob er dem Zertifikat vertrauen und darüber eine Verbindung initiieren möchte. Im Prinzip war es das, nur wie kommt hier ein CA ins Spiel ?
Wer sich ein self-signed Zertifikat erstellt, hat neben dem CA-Zertifikatsschlüssel nun auch ein eigenes CA-Root-Zertifikat. Das CA-Zertifikat können wir dazu nutzen eigene Zertifikate zu erstellen, wie jeder andere CA auch, nur ist dieses CA-Zertifikat nirgendwo in einer CA-Liste eingetragen und wird daher von allen Besuchern/Benutzern als nicht vertrauenswürdig eingestuft. Man kann das eigene CA-Zertifikat in CA-Listen händisch eintragen und dann vertrauenswürdige Zertifikate erstellen. Das gilt selbstverständlich nur auf den Rechner, wo das CA-Zertifikat eingetragen wurde.
Eigenes CA-Zertifkat erstellen
openssl req -x509 -newkey rsa:4096 -keyout tls.ca.key -out tls.ca -days 3650
Request für ein Zertifikat erstellen
openssl req -new -key tls.key -out tls.csr
Öffentliches Zertifkat erstellen
openssl x509 -req -sha256 -days 365 -in tls.csr -signkey tls.ca.key -out tls.crt
Wir haben nun folgende Dateistruktur:
tls.ca.key - Der private CA-Zertifikatsschlüssel
tls.ca.crt - Das öffentliche CA-Zertifikat für unsere Benutzer/Besucher (CA-Liste)
tls.csr - Die Datei für den Zertifikatsrequest (Nach Estellung überflüssig)
tls.crt - Das öffentliche Zertifikat für unsere Benutzer/Besucher
tls.key - Der private Zertifikatsschlüssel vom öffentlichem Zertifikat
Wie bekomme ich ein vertrauenswürdiges Zertifikat
Wenn wir nun ein global vertrauenswürdiges Zertifikat nutzen möchten, müssen wir uns an einen registrierten CA wenden. Es gibt etliche Anbieter wie zum Beispiel Comodo, SwissSign usw. diese möchten für das Zertifikat bzw. für die Dienstleistung bezahlt werden. Seit kurzem gibt es den CA Let’s Encrypt, der einfache Zertifikate kostenfrei anbietet. Diese sind allerdings nicht immer die beste Lösung und der Bestellvorgang ist anders, daher erkläre ich ihn einem eigenständigen Blogeintrag. Wer sich nun an einen der herkömmlichen CAs wendet, wird aufgefordert ein Anfrage für ein Zertifikat zu erzeugen (CSR). Ich erkläre wie folgt das erstellen eines Requests - Bitte achtete darauf, das der Key immer geheim und in eurem Besitz bleibt, gebt ihn niemals raus, selbst wenn euch jemand Schokolade dafür anbietet!
Ich lege zunächst eine Verzeichnis-Hierarchie an und wechsele dort hin
mkdir -p /opt/certificates/meineDomain.de
cd /opt/certificates/meineDomain.de
Jetzt erstelle wir ein Request
openssl req -new -nodes -keyout tls.key -out tls.csr -newkey rsa:4096
Dieser benötigt noch ein paar grundlegende Daten. Hier mit ein paar Beispieleingabe
Country Name (2 letter code) [AU]: DE
State or Province Name (full name) [Some-State]: Nordrhein-Westfalen
Locality Name (eg, city) []: Cologne
Organization Name (eg, company) [Internet Widgits Pty Ltd]: meineDomain
Organizational Unit Name (eg, section) []: Technology
Common Name (e.g. server FQDN or YOUR name) []: www.meineDomain.de
Email Address []: webmaster@meineDomain.de
Wenn ihr nach einem Passwort gefragt werdet, einfach mit Enter (kein Password) durch springen. Nun sollten im Verzeichnis der private Zertifikatsschlüssel tls.key und der Zertifikatsrequest tls.csr liegen. Wir sollten vor dem Versand allerdings noch testen, ob unser Zertifikatsrequest wirklich auf unser Zertifikatsschlüssel matched. Sind die beiden Hashs gleich, können wir das CSR mit guten Gewissen dem CA zu schicken.
Check: Passt der Request zum Schlüssel
openssl req -noout -modulus -in tls.csr | openssl md5
openssl rsa -noout -modulus -in tls.key | openssl md5
Wenn wir nun das CSR an einen CA schicken, wird er uns den öffentlichen teil des Zertifikates zurückschicken. Meist liegen dem Zertifikat noch ein benötigtes Zwischenzertifikate bei, davon habe ich bewusst bis jetzt noch nichts erwähnt.
Was ist ein Zwischenzertifikat
Ein CA hat meist mindestens ein CA-Root-Zertifikat und es gibt etliche Gründe für einen CA benötigte Zertifikate nicht direkt mit dem CA-Root-Zertifikat zu erstellen, sondern mit einem davon abgeleiteten Zertifikat. Das Problem dabei ist, das die Zwischenzertifikate (Intermediate) bei den Applikationen und Betriebssystemen meist nicht hinterlegt sind, sondern nur das CA-Root-Zertifikat, worauf sich das Zwischenzertifikat beruft.
Klasse noch ein Zertifikat \o/ Unser Zertifikat beruht mit hoher Wahrscheinlichkeit auf einem oder meheren Zwischenzertifikaten (Intermediates), welche sich wiederum auf eine CA-Root-Zertifikat beruft. Man nennt diese Vertrauensketten grundsätzlich TrustChain, egal wie viele Zertifikate in der Kette enthalten sind. Wir müssen also dem Client höchstwahrscheinlich nicht nur unser schickes öffentliche Zertifikat bereitstellen, sondern auch noch das Zwischenzertifikat, damit die Applikation den Bogen von unserem öffentlichem Zertifikat bis zum CA-Root-Zertifikat schlagen kann.
Ich lege die Zwischenzertifikate nochmals in einer separaten Datei an. Wir haben also unter Umständen folgende Dateistruktur:
tls.key - Der private Zertifikatsschlüssel
tls.csr - Die Datei für den Zertifikatsrequest (Nach Bestellung überflüssig)
tls.crt - Das öffentliche Zertifikat für unsere Benutzer/Besucher
tls.chain - Evtl. Zwischenzertifikate
Nun haben wir ein komplettes Set für ein vertrauenswürdiges Zertifikat :) Bitte beachtet, dass das CA-Root-Zertifikat in der Regel nicht an den Client ausgeliefert werden muss und daher auch nicht mitgesendet werden sollte - das steht schon in den CA-Listen !
Wie überprüfe ich die Zertifikate
Bevor man Zertifikate einsetzt, sollte man einige Punkte vor ab klären. Nicht denken oder hoffen, dass alles seine Richtigkeit hat, da der Bestellprozess für ein Zertifikat teils hochgradig automatisiert ist wird auch viel Unsinn ausgeliefert. Drum prüfe …
Um vorab zu prüfen, ob das öffentliche Zertifikat mit unserem privaten Zertifikatsschlüssel überhaupt funktionieren kann, sollte man sich zwei Prüfsummen erzeugen lassen und vergleichen. Sind sie unterschiedlich, dann passt das Zertifikat nicht zum privaten Schlüssel und ist nutzlos.
Check 1: Passt das öffentliche Zertifkat zum Zertifikatsschlüssel
openssl x509 -noout -modulus -in tls.crt | openssl md5
openssl rsa -noout -modulus -in tls.key | openssl md5
Sollte der Check fehlschlagen, hat der CA beim erstellen des Zertifikats Mist gebaut und ihr müsst ihm den Request nochmals zu senden.
Check 2: Ist das Zertifikat für meine Domain gültig bzw. für welche wurde es ausgetstellt
Wichtig ist auch das Prüfen, für welche Domains/Subdomains das Zertifikat gültig ist
openssl x509 -in tls.crt -text -noout | grep DNS
Wie lese ich die Zertifikate aus
Jedes Zertifikat hat eine ganze menge Informationen inne. Neben dem Zertifikatsinhaber und Zertifikatsaussteller sind dort wichtige Prüfsummen z.B. für die TrustChain. Diese ganzen Informationen kann man wie folgt anzeigen lassen.
(Zwischen)Zertifikate
openssl x509 -in tls.crt -text -noout
Zertifikatsschlüssel
openssl rsa -in tls.key -text -noout
Requests
openssl req -in tls.csr -text -noout
Jetzt habe ich den Überblick verloren
Gut, das passiert :) Wenn ich z.B. plötzlich alle Zertifikate in einer Datei habe oder die Dateien alle mit .crt aufhören, wird eine Differenzierung etwas komplizierter. Lasst uns kurz in dem Aufbau von Zertifikaten und deren Fingerprints versinken…
Ein Zertifikatsschlüssel hat immer folgenden Aufbau
—–BEGIN PRIVATE KEY—–
…
—–END PRIVATE KEY—–
Ein Zertifikatsrequest hat immer folgenden Aufbau
—–BEGIN CERTIFICATE REQUEST—–
…
—–END CERTIFICATE REQUEST—–
Unser öffentliches Zertifikat und die komplette TrustChain hat hingegen immer folgenden Aufbau und lässt sich daher nicht so genau differenzieren.
—–BEGIN CERTIFICATE —–
…
—–END CERTIFICATE —–
Was wir nun machen können ist der Vergleich der Fingerprints und den so oft erwähnten “Verweis” auf das bürgende Zertifikat. Hier ein Beispiel.
Erstes Zertifikat
X509v3 Authority Key Identifier: keyid:90:AF:6A:3A:94:5A:0B:D8:90:EA:12:56:73:DF:43:B4:3A:28:DA:E7
X509v3 Subject Key Identifier: 7C:4B:C5:9A:BE:87:FD:7D:B8:BD:5C:14:6E:55:42:9D:2F:A4:1C:41
Zweites Zertifikat
X509v3 Authority Key Identifier: keyid:BB:AF:7E:02:3D:FA:A6:F1:3C:84:8E:AD:EE:38:98:EC:D9:32:32:D4
X509v3 Subject Key Identifier: 90:AF:6A:3A:94:5A:0B:D8:90:EA:12:56:73:DF:43:B4:3A:28:DA:E7
Man sieht beim ersten Zertifikat den Fingerprint unter “Subject Key Identifier” und den Fingerprint des bürgenden Zertifikates unter “Authority Key Identifier”. Wenn wir nun ein Zertifikat finden, dass den Fingerprint “Authority Key Identifier” als “Subject Key Identifier” hält, haben wir es gefunden. In diesem Falle ist das zweite Zertifikat aber es ist nicht das letzte Zertifikat, da es ebenfalls wieder ein Verweis auf einen weiteren “Authority Key Identifier” trägt. Das dritte Zertifikat habe ich dann im Netz, anhand des Fingerprints, gefunden - siehe unten
Drittes Zertifikat
X509v3 Subject Key Identifier: BB:AF:7E:02:3D:FA:A6:F1:3C:84:8E:AD:EE:38:98:EC:D9:32:32:D4
Das 3. Zertifikat hat nun kein Verweis mehr auf ein anderen “Authority Key Identifier” und ist damit das letzte Zertifkat in der Kette (TrustChain), das sogenannte CA-Root-Zertifikat. Das Zertifikat brauchen wir in der Regel nicht, aber falls doch z.B. für andere Zertifkatsformate, dann speichert es euch extra ab z.B. als tls.root, denn was man hat …