Client-Certificates
« | 27 Nov 2022 | »Für gewöhnlich möchten im Web nur die Clients (also unsere Browser) wissen, ob sie auch mit der richtigen Gegenseite reden, folglich stellen nur Server ihre Zertifikate zur Einsicht bereit.
Doch wenn es um Sicherheit geht, dann muss auch der Server wissen, ob seine Clients “die richtigen” sind. Genau hier kommen Client-Zertifikate ins Spiel.
Wiederholungsstunde: Zertifiakte
Beim üblichen TLS Handshake schickt der Server den öffentlichen Teil seines Zertifikats an den Client und der kann es dann verifizieren oder ignorieren. Das geschieht über die Liste der “vertrauenswürdigen” Zertifikate, die entweder im Betriebssystem oder in der Anwendung selbst hinterlegt sind.
Zertifikate können bekanntlich untereinander verknüpft sein und deshalb existieren “Stamm-Zertifikate” (Root Certificates), die überall bekannt sein sollten, und für jede Anwendung oder Domäne eigene Zertifikate, die mit bestimmten Stamm-Zertifikaten signiert wurden.
Der Client hat also entweder das empfange Zertifikat bereits als “sicher” in seiner Datenbank, oder er erkennt das Stammzertifikat als korrekt an.
Bei Webanwendungen und HTTPS gibt es noch ein Kriterium: Es muss nämlich
auch der im Zertifikat enthaltene “Name” korrekt sein.
Wenn man also “https://opengate.at” aufruft, muss das Zertifikat als
“vertraut” (trustet) gelten, und außerdem muss das Zertifikat auch den
Namen “opengate.at” beinhalten.
Passt das nicht, wird die Verbindung abgelehnt, außer man zwingt den Browser, Zertifikatsfehler zu ignorieren.
Client Zertifikate
Bei Client-Zertifikaten entscheidet der Server, …
- ob ihn diese gar nicht interessieren.
- ob sie optional mitgeschickt werden dürfen.
- ob sie zwingend erforderlich sind.
Der Client kann bzw. muss dann sein Zertifikat an den Server senden, und dieser leitet dann die gleiche Prozedur ein, die ansonsten auch der Client anwendet:
- Prüfung, ob das Zertifikat oder sein “Stamm” vertrauenswürdig sind
- Prüfung, ob der übermittelte Name auch korrekt ist.
Problem: Namensprüfung
Perfekt funktioniert das nur in einem perfekten Adress- bzw. Namensraum. In einem Active-Directory hätten alle Server und Clients einen im DNS registrierten Hostnamen, womit auch für jeden Client ein Zertifikat mit diesem Namen ausgestellt werden kann.
In IOT Netzen sieht das aber leider ganz anders aus. Oft werden die
Clients dort per IP-Adresse konfiguriert und DNS vollkommen ausgespart.
Natürlich kann ein Zertifikat auch auf einen IP-Adresse lauten … doch
das geht dann nur, wenn diese statisch ist.
Wenn aber die Clients per DHCP bei jedem Start eine neue IP erhalten,
müssten sie auch ein neues Zertifikat ausgerollt bekommen, denn der
Server würde dann nur die IP des Clients erkennen und keinen Namen
ableiten können.
Genau dieses Problem stellt aktuell viele Bereiche vor Probleme. Denn einerseits verlangen immer mehr Endkunden erhöhte Sicherheit mit Zertifikaten, andererseits sind zumindest Clientzertifikate nicht in allen Bereichen einsetzbar.
Zertifikate anlegen
Wer keine fertige Zertifikatsinfrastruktur zur Verfügung hat, dem bleibt dann
nur der Griff zum openssl
Tool, um selbst-signierte Zertifikate anzulegen.
- Erzeugung eines Stamm-Zertifikats (Certificate Authority)
openssl req -x509 -sha256 -days 3650 -nodes -newkey rsa:2048 -subj "/C=AT/L=Vienna/O=OpenGATE/OU=Carbis" -keyout ca-key.pem -out ca.pem
- Wir erhalten die Datei
ca-key.pem
undca.pem
- Erzeugung eines Signier-Anfrage für ein neues Zertifikats
openssl req -newkey rsa:2048 -days 3650 -nodes -subj "/C=AT/L=Vienna/O=OpenGATE/OU=Carbis/CN=127.0.0.1/emailAddress=admin@example.com" -keyout cert-key.pem -out request.csr
- Erzeugt
cert-key.pem
mit dem Schlüssel undrequest.csr
für die Signieranfrage
- Signiert und erstellt ein neues Zertifikat:
openssl x509 -req -in request.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -days 3650 -sha256 -out cert.pem
- Erzeugt
cert.pem
mit dem per CA signiertem Zertifikat.
- Erzeugung eines Zertifikates ohne CA Signatur
openssl req -new -x509 -days 3650 -nodes -subj "/C=AT/L=Vienna/O=OpenGATE/OU=Carbis/CN=127.0.0.1/emailAddress=admin@example.com" -keyout cert-key.pem -out cert.pem
- Erzeugt
cert-key.pem
mit dem privaten Schlüssel undcert.pem
mit dem Zertifikat.
Nun kann man am Server entweder das Stammzertifikat (CA) als vertrauenswürdig
hinzufügen, womit alle Zertifikate, die damit signiert wurden auch
vertrauenswürdig sind (ca.pem
).
Oder man fügt jedes einzelne Zertifikat dem Server als vertrauenswürdig hinzu
(also die cert.pem
Varianten).
Die Clients selbst nutzen dann den privaten Schlüssel (cert-key.pem
) um die
Kommunikationsdaten zu signieren und der Server kann die Signatur über sein(e)
Zertifikat(e) bestätigen.
Fazit
Zertifikate waren für mich immer “kompliziert”, weil meistens etwas nicht
richtig funktioniert hatte.
Doch meist lag es an falschen Hostnamen oder anderen Konfigurationsfehlern.
Inzwischen freue ich mich, dass ich zumindest die Grundbegriffe von
verschlüsselter Kommunikation auch selbst nachimplementieren kann.
openssl
ist hierfür ein mächtiges und gleichsam nützliches Werkzeug.