Public key pins, a new safeguard for HTTPS websites


Public-Key-Pins will be the new HTTP header to inform user browsers what X.509 certificates are identifying the websites and prevent various forms of man-in-the-middle attacks on SSL.

The SSL/TLS protocol is seemingly a significant pain for countries and companies monitoring their Internet users, especially since Twitter, Facebook and Google offered SSL-enabled versions of their popular products. Need is mother of invention, so wiretapping solution provides started producing new methods of bypassing SSL, such as SSL striping, downgrade or man-in-the-middle (MITM) attacks.

The latter should be theoretically prevented by the X.509 certification model, but with Windows and Firefox trust anchors now growing to hundreds of certificates and incorporating certification authorities from potentially wiretapping countries, SSL site owners gradually stop trusting the X.509 model.

The first safeguard of the new type was Strict Transport Security HTTP header, which basically allows the website owner to announce that under no circumstances it should be viewed without SSL enabled. If this information is then being memorized in user browsers for sufficiently long time, it significantly reduces possibility of SSL striping attacks. For example, this header would instruct browsers visiting a website to memorize the SSL decision for 185 days, which means for the next half year browser will reject opening this page if it's not over valid SSL connection:

Strict-Transport-Security: max-age=16070400

Public key pinning goes a step further — it instructs browsers to memorize website's SSL certificate's hash, so that the certificate cannot be replaced by a malicious one. This header would instruct the browser to remember the website's public keys hashes for the next 30 days:

Public-Key-Pins: max-age=2592000;

These BASE64 strings are generated from the PEM encoded public key certificate as used on the SSL/TLS web server:

openssl x509 -noout -in certificate.pem -pubkey |  openssl asn1parse -noout -inform pem -out public.key
openssl dgst -sha256 -binary public.key | openssl enc -base64

Public key pins status

Public key pins were standardized in RFC 7469: Public Key Pinning Extension for HTTP. My other website checks for PKP headers among others and as of 2015 there is a few dozens of websites using it ( » HTTP headers » Public-Key-Pins, note that there's also the Public-Key-Pins-Report-Only variant which is non-enforcing). Hopefully, as the header is now HTTP standard it will get more popularity.

ShodanHQ finds over 200 websites using it, most notably Freenet Project (see report).

How does it fit X.509 model?

If you look at the history and overall architecture of X.509, the introduction of PKP can be seen as a kind of failure of the X.509 model. But it's really not — X.509 answers the question of "is this certificate trusted", implied from "is it signed by a trusted authority".

But X.509 neither does nor it ever has answered the question of "should this authority actually sign this certificate", because in the X.509 model all certificate authorities were considered trusted. So PKP seems to be filling this gap, by giving webmasters additional possibility to announce what public key is the right one.


Comment viewing options

This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Select your preferred way to display the comments and click "Save settings" to activate your changes.

What about new visitor at secure page for which certificate will expire in time shorter that PKP limit? Is the renewed certificate will be rejected by visitor browser even if is valid? I think so. This can be big issue for implementing PKP in business sites.

I think this is already considered in the PKP spec. As the date of cert expiration approaches, you can set PKP time to smaller values or even zero, which will cancel the pin. So in general the rule of thumb should be that if your cert is going to be valid for 2 years from now on, set the pin for something like 6 or 3 months.

Correct me if I'm wrong here. This means browser will pin specific certificate which was pointed by those headers. So, if user opens a page for the first time during MitM attack, it would use spoofed certificate as pinned, discarding valid one for arbitrary period of time..

Correct — and if there's an ongoing MITM, you can also spoof the PKP header. On the other side, when the MITM is finished and you visit the website again the browser will reject the connection because the legitimate certificate won't match.