HTTP Public Key Pinning (HPKP)

0

Die IETF (Internet Engineering Task Force) steht kurz vor der Verabschiedung von HTTP Public Key Pinning als weiteren Standard. HPKP ist eine Technik, die Webseitenbetreibern die Möglichkeit bieten, durch das ausliefern eines speziellen HTTP Headers mit das SSL Zertifikat an die Webseite zu "pinnnen". Ein Client welcher einmal diese Webseite besucht hat ist anschließend für eine vom Webseitenbetreiber definierte Zeit in der Lage einen unberechtigten Wechsel des SSL Zertifikates zu erkennen. Diese Technik soll die Lücke schließen, welche dadurch ensteht, das bei verschiedenen Zertifikatsstellen ein SSL Zertifikat für ein und dieselbe Domain ausgestellt werden kann.Dies ist aktuell noch möglich, da für eine Domain von jeder gültigen CA ein Zertifikat für eine Webseite ausgestellt werde kann und dieses auch von allen Clients als gültig anerkannt wird, solange die Clients der Root CA vertrauen.

Wie funktioniert HPKP

Durch das Key Pinning kann der Webseitenbetreiber einen HTTP Header mit ausliefern, welcher den gehashten Wert von Zertifkaten aus der Zertifizierungskette beinhaltet. Auf welche Zertifikate hierbei in Form von Hashes verwiesen wird ist dabei egal. Es ist also möglich, dass Zertifikat der Root-CA sowie das eigene Zertifikat anzugeben. Somit ist ein Client nach dem einmalgen Besuch einer Webseite über HTTPS also in der Lage zu erkennen, ob die Zertifikate noch mit denen, des vorherigen Besuches übereinstimmen. Durch einen Alerungswert, kann der Webseitenbetreiber die maximale Laufzeit dieser Cache-Werte festlegen.

Ein Beispiel für einen Key-Pinning Header ist:

<IfModule mod_headers.c>
   Header always set Public-Key-Pins "pin-sha256="kb6xLprt35abNnSn74my4Dkfya9arbk5zN5a60YzuqE="; pin-sha256="Q7TFaToJQRkpKkHoU23mFcGODWeaUM6tpYw5A/NJQYg="; max-age=300;"
</IfModule>

Erstellen des HTTP Headers

Um einen Key Pinning Header zu erstellen, gibt es verschiedene Möglichkeiten. Eine Möglichkeit ist die Verwendung der bash. Hierzu kann der CSR (Certificate Singing request), das Zertifikat oder der private Schlüssel als Grundlage verwendet werden.

# CSR
openssl req -in test.csr -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

 

# PEM
openssl x509 -in test.pem -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

 

# KEY
openssl rsa -in test.key -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64

Es geht gibt auch die Möglichkeit, diesen über eine Webinterface wie das von report-uri.io zu erstellen. In beiden Fällen wird lediglich der pin generiert. Der HTTP-Header muss anschließend selber zusammengesetzt werden.

Bei der Erstellung des Key-Pin Headers ist wichtig, dass immer eine Backup-Key hinterlegt wird. Andernfalls wird der HPKP Header nicht als gültig anerkannt. Mehr dazu gleich.

Mögliche Parameter

Bei der Erstellung des HTTP Headers gibt es vier Parameter, welcher verwendet werden können.

Public-Key-Pins-Report-Only / Public-Key-Pins

Public-Key-Pins-Report-Only teilt dem Client mit, dass eine Abweichung des HPKP vom verwendeten Zertifikat nur Reported werden soll. Public-Key-Pins hingegen lässt den Client die Verbindung mit einem Fehler beenden.

pin-sha256

Dieser Parameter beinhaltet den Fingerabdruck des zu pinnenden Zertifikates im Base64 Format und kann für mehrere Zertifikate entsprechend merhfach verwendet werden. Es kann zum Beispiel der Fingerabdruck des Webseitenzertifikates angepinnt werden, der Fingerabdruck einer Zwischenzertifizierungsstell, der Root CA oder eine Kombination aus allen.

max-age
Gibt die Gültigkeitsdaure der Pinning-Informationen für den Client nach dem ersten Besuch in Sekunden an.

includeSubdomains (Optional)
Hiermit kann festgestelt werden, ob die Pinning-Informationen auch für alle Subdomains gültig sind. Dies wäre zum Beispiel bei einem Wilrdcard Zertifikat der Fall.

report-uri (Optional)
Diesre Parameter kann verwendet werden um im Falle von fehlerhaften Key-Pinning Informationen eine Rückmeldung der Clients zu erhalten. Die im rport-uri angegebene Adresse muss in der Lage sein, per POST Befehl Informationen verarbeiten zu können. Ein Beispielskript von Hanno Böcken gibt es hier (blog.cscholz.io mirror). Es gibt auch die Möglichkeit, das Reporting über die Webseite von https://report-uri.io laufen zu lassen. Bei der Verwendung des Skriptes sind zwei Dinge zu beachten:

  • die verwendete Adresse darf nicht identisch mit der zu überwachenden Domain sein oder muss per http erreichbar sein, da andernfalls ein falscher Key-Pin den Aufruf der report-uri Adresse für den Client sperrt.
  • die im Falle von Hanno Böcken verwendete Log-Datei darf von extern nicht erreichbar sein, da andernfalls Informationen über Webseitenbesucher sowie den Webserver preisgibt.

HPKP Validierung

Um die HPKP Verwendung zu validieren, gibt es mehrere Möglichkeiten.

Einmal kann man sich über die Bash den HTTP Header direkt anzeigen lassen und die Werte mit den eingstellten Header-Werten abgleichen.

$ curl -I https://blog.cscholz.io
HTTP/1.1 200 OK
Date: Thu, 22 Jan 2015 21:00:29 GMT
Server: Apache
X-Pingback: https://blog.cscholz.io/xmlrpc.php
Strict-Transport-Security: max-age=604800;
Public-Key-Pins: pin-sha256="Q7TFaToJQRkpKkHoU23mFcGODWeaUM6tpYw5A/NJQYg="; pin-sha256="kb6xLprt35abNnSn74my4Dkfya9arbk5zN5a60YzuqE="; max-age=604800
Vary: Accept-Encoding
Content-Type: text/html; charset=UTF-8

Dies geht ebenfalls über die Webseite von https://report-uri.io/.

Noch benutzerfreundlichsten geht es jedoch über die Webseite von ssllabs.com. Im dortigen SSL Report

hpkp-report

Probleme beim SSL Zertifikats Wechsel vermeiden

Sobald man HPKP verwendet, sollte man sich Gedanken um den nächsten Zertifikatswechsel machen. Denn wechselt man das Zertifikat kurzfristig und pinnt das neue Zertifikat nicht rechtzeitig im Header an, verweigern alle Clients, welche die Webseite vorher einmal besucht haben mind. die im max-age angegebene Zeit die Verbindung.

Um hier Probleme zu vermeiden muss der neue Zertifikats-Pin rechtzeitig zum bestehenden veröffentlicht werden, so das vor dem Zertifikatswechsel der max-age Wert der Client mind. einmal abläuft. Dies führt dazu, dass die Clients den Key-Pin des alten sowie neuen Zertifiaktes kennen und bei einem Austausch das neue sofort als gültig anerkennen. Wie oben beschrieben lässt sich der Fingerabdruck eines Zertifikates bereits anhand des CSR erstellen. Somit kann der neue Key-Pin bereits veröffentlicht werden, noch bevor der neue Zertifikatsantrag bei einer CA eingereicht wurde.

hpkp-change

Aus diesem Grund sieht der HPKP Standard vor, dass immer ein Backup-Pin mit angegeben wird. Andernfalls wird der HPKP nicht als gültig anerkannt.

Neue Zertifikatsanforderung für Backup-Pin

Eine neue Zertifikatsanforderung für einen Backup-Pin kann man ohne Probleme für einen bereits bestehenden privaten Schlüssel erstellen.

openssl req -new -key rsa:2048 -nodes -out domain.pre-csr -key domain.key -subj "/C=DE/ST=/L=/O=/CN=domain.de emailAddress=postmaster@domain.de"

HPKP Überprüfung im Browser

Browser HPKP Support HPKP Reporting Fehlermeldung

Firefox
 

35
 

N/A
 

firefox_hpkpfail

Google Chrome
 

38
 

46
 

chrome_hpkpfail


Internet Explorer


N/A

N/A
 

Firefox unterstützt ab Version 35 die HPKP Validierung Chrome ab Version 38. Ab Chrome v. 46 wird auch die Reporting Funktion unterstützt.

 

Links

Wie der Header erstellt werden kann, beschreiben folgende Seiten bzw. Tools

Nachtrag vom 17.01.2015

Hier gibt es eine aktuelle Auflistung, welcher Browser ab welcher Version HPKP unterstützt und auch, wie die Meldung des jeweiligen Browser aussieht.

Links

Teilen.

Über den Autor

Seit der Ausbildung zum Fachinformatiker Systemintegration (2002-2005) bei der DaimlerChrysler AG, beruflich im Bereich der E-Mail Kommunikation (Exchange, Linux) sowie des ActiveDirectory, mit entsprechenden Zertifizierungen (MCSE 2003, MCITP Ent.-Admin 2008, MCSE 2012, LPIC 1-3) tätig. Abgeschlossenes Studium zum Master of Science der IT-Management an der FOM sowie zertifizierter Datenschutzbeauftragter. Aktuell im Projektmanagement tätig.

Antworten