Public Key Pinning, kurz HPKP, gehört zu den Verfahren, die die Sicherheit von SSL-Zertifikaten immens erhöhen können. Zweck von HPKP ist es, festzustellen, wann sich der öffentliche Schlüssel eines Zertifikats für einen bestimmten Host geändert hat. Dies kann ohne HPKP etwa dann passieren, wenn ein Angreifer eine Certification Authority (CA) dermaßen beeinträchtigt, dass gültige Zertifikate für beliebige Domains ausgegeben werden können. Ein recht prominentes Beispiel dafür war die Ausstellung falscher Microsoft-Zertifikate, über die wir in unserem Blog berichtet haben.
Ist eine TLS-Verbindung mit dem Server hergestellt, sucht der Browser bei der Verwendung von HPKP jede gespeicherte Pin für den jeweiligen Hostnamen heraus und prüft, ob einer der gespeicherten Pins mit denen des SPKI-Fingerprints (= Ergebnis der SHA256-Anwendung auf die Public Key-Info) in der Zertifikatskette übereinstimmt. Scheitert diese Pin-Verifizierung, so muss die Verbindung unter HPKP sofort abgebrochen werden. Ist serverseitig kein HPKP konfiguriert oder unterstützt der Browser HPKP nicht, kommt die Verbindung dennoch zustande.
Private Schlüssel generieren (einen primären und einen backup Key)
openssl genrsa -out www.hpkp-faq.de.key1.key 2048
openssl genrsa -out www.hpkp-faq.de.key1.key 2048
CSRs erstellen (für beide private Keys)
openssl req -new -sha256 -key www.hpkp-faq.de.key1.key -out www.hpkp-faq.de.csr
openssl req -new -sha256 -key www.hpkp-faq.de.key2.key -out www.hpkp-faq.de.backup-csr.csr
SPKI Fingerprints von beiden öffentlichen Schlüsseln generieren
openssl req -pubkey openssl dgst -sha256 -binary | base64
hIBFVXDUBPQgeRapi9m71<wbr />27NhGkTc+QS4EHq2LyBA=
openssl req -pubkey -outform der | openssl dgst -sha256 -binary | base64
ZrYB07EvOX0HjbBTjJp3lt2<wbr />2nGJGqYDGU21ZnBzb8=
virtual Host Konfiguration anpassen
Header always set Public-Key-Pins-Report-Only: ‚max-age=5184000;
pin-sha256=“hIBFVXDUBPQgeRapi9mRB7<wbr />127NhGkTc+QS4EHq2LyBA=“;
pin-sha256=“ZrYB07EvOX0HjbBTjJp3lEMt2<wbr />2nGJGqYDGU21ZnBzb8=“‘
Pinnen der beiden öffentlichen Schlüssel
Alternativ gibt es die Möglichkeit, vorab im Testmodus zu starten. Hierfür geben Sie "Header always set Public-Key-Pins-Report-Only" anstatt "Header always set Public-Key-Pins"an:
Header always set Public-Key-Pins-Report-Only: ‚max-age=5184000;
pin-sha256=“hIBFVXDUBPQgeRapi9mRB71<wbr />27NhGkTc+QS4EHq2LyBA=“;
pin-sha256=“ZrYB07EvOX0HjbBTjJp3lEMt22<wbr />nGJGqYDGU21ZnBzb8=“‘
Mittels curl – I https:// www.beispiel.de können Sie sich den Header auf der Konsole anzeigen lassen.
Der HTTP Header bei HPKP kann wie folgt aussehen:
HTTP/1.1 200 OK
Date: Thu, 12 Nov 2015 10:45:37 GMT
Server: Apache
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Public-Key-Pins: max-age=5184000; pin-sha256=“hIBFVXDUBPQ
pin-sha256=“ZrYB07EvOX0HjbBTjJp3lE
report-uri=“https://report-uri.io/report/559ec66014
X-Powered-By: PHP/5.5.30 Content-Type: text/html; charset=UTF-8
Der Header spezifiziert für HPKP mindestens pin-sha256 Werte, d. h.: die Pins von zwei öffentlichen Schlüsseln. Dabei ist ein Pin der eines beliebigen öffentlichen Schlüssels, der sich in der aktuellen Zertifikatskette befindet, der andere ist der eines beliebigen öffentlichen Schlüssels, der sich nicht in der aktuellen Zertifikatskette befinden muss. Bei letzterem könnte es sich einen Backup-Schlüssel handeln, der beispielsweise dann zum Einsatz kommt, wenn Ihr Zertifikat abläuft oder zurückgezogen werden muss.
Senden Sie die Certificate Signing Request (CSR) mit Ihrem öffentlichen Schlüssel an eine Zertifizierungsstelle, stellt Ihnen diese ein gültiges Zertifikat aus. Dieses enthält den öffentlichen Schlüssel des RSA-Schlüsselpaars sowie ein Ablaufdatum. Sowohl der öffentliche Schlüssel als auch das Ablaufdatum werden von der Zertifizierungsstelle signiert, sodass jedwede Veränderungen an diesen beiden Komponenten das Zertifikat sofort ungültig werden lassen. X.509-Zertifikate enthalten auch andere Bereiche, um TLS-Verbindungen vernünftig zu authentifizieren, etwa den Hostnamen Ihres Servers sowie weitere Details.
Mit dem Befehl
openssl genrsa 2048
Erzeugen Sie einen 2.048-bit-RSA-Schlüssel und geben ihn auf der Konsole aus. Wenngleich es -----BEGIN RSA PRIVATE KEY----- heißt, wird nicht ausschließlich der private Schlüssel ausgegeben, sondern auch die ASN.1-Struktur, die ebenfalls einen öffentlichen Schlüssel enthält. So erzeugen Sie also ein RSA-Schlüsselpaar. Ein weit verbreiteter Irrtum in der Kryptographie besteht darin, dass der RSA-Schlüssel selbst für ein bestimmtes Zertifikat ablaufen kann. RSA-Schlüssel laufen jedoch nie ab – es sind letztlich nur Zahlen. Das Zertifikat jedoch, das den öffentlichen Schlüssel enthält, kann sehr wohl ablaufen. Deshalb kann auch nur das Zertifikat zurückgezogen werden. Die Schlüssel selbst laufen ab oder werden zurückgezogen, sobald es keine gültigen Zertifikate mehr gibt, die eben diesen öffentlichen Schlüssel verwenden, oder wenn Sie den Schlüssel vernichtet haben oder überhaupt aufgehört haben, diesen zu verwenden.
In Anbetracht all der genannten Szenarien fragen Sie sich vielleicht, welchen Schlüssel Sie am besten fürs Pinnen mit HPKP verwenden, und die Antwort kann nur lauten: Das kommt darauf an. Sie können einen oder alle öffentlichen Schlüssel in Ihrer Zertifikatskette pinnen, und das wird funktionieren. Die Spezifikation verlangt, dass Sie mindestens zwei Pins haben, sodass Sie den SPKI-Hash eines anderen Rootzertifikats einfügen müssen, ein anderes Zwischenzertifikat (eine andere Stufe Ihrer aktuellen CA würde auch funktionieren) oder ein anderes untergeordnetes Zertifikat. Die einzige Anforderung ist: Der Pin entspricht nicht dem Hashwert von irgendeinem Zertifikat innerhalb der aktuellen Kette. Der Browser kann nicht feststellen, ob Sie ihm ein gültiges, sinnvolles Backup bereitgestellt haben - weshalb er auch gerne Zufallswerte akzeptiert.
Beim Pinnen auf eine kleine Auswahl von CAs zurückzugreifen, bei denen Sie sich wohl und sicher fühlen, hilft Ihnen, das Risiko bei der Verwendung von HPKP weiter einzuschränken. Beim Pinnen nur Ihre untergeordneten Zertifikate zu verwenden, birgt ein erhöhtes Risiko, bietet jedoch mehr Sicherheit. Es ist ein bisschen wie Fahren ohne Gurt: Es funktioniert meistens, aber falls etwas schiefgeht, geht es in aller Regel so richtig schief. Und das wollen Sie sicherlich vermeiden.
Wenn Sie bei HPKP ausschließlich Ihre untergeordneten Zertifikate pinnen, besteht außerdem die Gefahr, dass Sie einen Backup-Schlüssel generieren, der an Uraltstandards festhält und vielleicht nicht mehr benutzt werden kann, wenn Sie Ihr aktuelles Zertifikat ersetzen müssen. Drehen wir die Uhr drei Jahre zurück. Ihr Backup-Key ist ein 1.024-Bit-RSA-Schlüsselpaar. Sie pinnen für ein Jahr, dann läuft das Zertifikat ab. Sie gehen zur CA und bitten um ein neues Zertifikat für Schlüssel A, die CA sagt jedoch, dass der Schüssel zu kurz und zu schwach ist. Sie fragen nach dem Backup-Schlüssel, der ebenfalls zurückgewiesen wird, weil er zu kurz ist. Ergebnis: Weil Sie beim Pinnen nur von Ihnen kontrollierte Schlüssel verwendet haben, sind sie nun quasi eingemauert bzw. sperren potenzielle Besucher Ihrer Website aus.
HTTP Public Key Pinning hat seinen Dienst geleistet – doch langsam nähert sich die Technik für Zertifikats-Pinning dem Ende ihrer Amtszeit. HPKP hat erstmalig einen Schutzmechanismus geschaffen, der anderweitig nicht möglich war. Doch mit diesem Schutz gingen auch Möglichkeiten einher, diesen Sicherheitsmechanismus auszunutzen. Die Begriffe „HPKP Suicide“ und „Ransom HPKP“ geben bereits einen Eindruck darüber, was mit HPKP im negativen Sinne machbar ist. Ab einem gewissen Punkt war sichtbar, dass HPKP mehr Probleme kreierte, als es löste und somit entschieden sich nun Firefox und Chrome diesem Verfahren nicht mehr zu vertrauen. Da es mittlerweile kaum noch Browser gibt, die die HPKP-Reports senden, ist es für Sie nun an der Zeit, dass HPKP von Ihrer Webseite verschwindet.