Dienstag, 22 Mai, 2018

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.


1. 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

2. 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


3. 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 ...