09.042014

Client-Zertifikate

Heute möchte ich euch eine Möglichkeit vorstellen, sich Client-seitig mit einem Zertifikat an einem Webserver zu authentifizieren.

Ein Server-Zertifikat ist dafür geeignet eine verschlüsselte Kommunikation zu ermöglichen.
Ein Client-Zertifikat jedoch, dient zur Authentifizierung eines Besuchers.

Falls jedem Benutzer ein eigenes Zertifikat zugeteilt ist, ist die Abfrage dieses gleichzusetzen mit einem Login. Es kann jedoch auch als zusätzliche Sicherheitsmaßnahme dienen. Basis für den Einsatz von Client-Zertifikaten ist eine HTTPS Veschlüsselung. Um die Client-Zertifikate zu signieren wird ein Server Zertifikat benötigt. Dies kann ein selbst signiertes oder aber auch ein richtiges Zertifikat sein. Ein Client-Zertifikat lässt sich mit dem openssl Befehl wie folgt erstellen:

openssl genrsa -des3 -out file.key
openssl req -new -key file.key -out file.req
openssl ca -cert /pfad/zum/serverzertifikat.crt -keyfile /pfad/zum/serverzertifikat.key -out file.crt -in file.req

Das erste Client-Zertifikat wurde erzeugt und mit dem Server-Zertifikat signiert.

Damit die meisten Browser das Client-Zertifikat nutzen können, muss es in das PKCS#12 Format umgewandelt werden:
openssl pkcs12 -export -inkey file.key -name "file" -in file.crt -certfile /pfad/zum/serverzertifikat.crt -out file.p12

Als nächstes muss nun die Server-Konfiguration angepasst werden. Hier als Beispiel mit dem Apache HTTP Server:

<VirtualHost *:443>
...
SSLCACertificateFile /pfad/zum/serverzertifikat.crt
SSLVerifyClient require|optional
SSLVerifyDepth 1
SSLOptions +StdEnvVars
...
</VirtualHost>

SSLVerifyClient kann "require" oder "optional" sein.
Zu den SSLOptions kann zusätzlich noch "+ExportCertData" hinzugefügt werden. Dann steht das Zertifikat auch in PHP zur Verfügung.

Nach einem Neustart des Webservers fragt der Webserver nach einem Zertifikat.

Zuletzt muss das Client-Zertifikat noch in den Browser importiert werden.
In Google Chrome importiert man das Client-Zertifikat unter:
Optionen -> Details -> HTTPS -> Zertifikate verwalten

Nun wird das Zertifikat vom Browser an den Server geschickt.
Wenn die Server-Einstellung SSLVerifyClient auf require gesetzt ist, wird ein gültiges Zertifikat erwartet und im Fehlerfall ein SSL-Verbindungsfehler zurückgegeben.

In PHP können wir nun auf die Daten des Client-Zertifikats mit Hilfe des $_SERVER Arrays zugreifen.