HPKP: What is behind the public-key pinning extension for HTTP
Secure transmission channels are an important prerequisite for working with digital data. It is of particular importance to have a completely secured path during a data transmission when you are sending and receiving data packets remotely or while on the move. It is no accident that confidential information is only transmitted via VPN or SSL/TLS connections. Enterprises and facilities with their own DNS servers and selected certification bodies ensure that these protocol technologies are almost untouchable. However, users who are active outside of these structures are subject to the public DNS and site certificate hierarchy, which significantly increases the likelihood of a man-in-the-middle attack on their data. The main reason for the increased security risks are counterfeit certificates issued by dubious or infiltrated certification authorities. The user relies on the connection and all their data being secure, while the trusting authority is paradoxically responsible for the opposite. With the so-called HTTP Public Key Pinning (HPKP), Google brought a solution into play in 2011 that is now available in the RFC 7469 as standard.
What is HPKP?
Public key pinning is an extension to the Hypertext Transfer Protocol (HTTP), which allows you to assign the public key set for future SSL/TLS connections to a host. By doing this, an accessing client will find out which public keys they can trust when connecting to that host during the first contact. This is also referred to as a ‘Trust on First Use’ (‘Trust in first application’). Each entry of a verified key is called a pin, which is where the mechanism gets its name. All pins created are sent to the client in the HTTP header and are then saved for a specific time.
When a new connection request is made, the client checks whether the certification chain proposed for the SSL/TLS transmission contains a public key, which was previously sent via HPKP. If this is not the case, for example if it was a fake certificate, an error message will be generated and the connection will not be made. This verification process is also referred to as pin validation. The entries of the pins in the HTTP header look something like this:
Public-Key-Pins:
pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=";
pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=";
max-age=2592000; includeSubDomains; report-uri="http://example.com/pkp-report"
The example shows all four directives that can contain a pin entry in the HTTP header:
- pin: The pin directive is the most important part of the entry, and consists of a name and a value. The name provides conclusions about the algorithm used for the encryption. SHA256 is the only one possible to date. The hash value, which is within quotation marks, is a Base64 encoded string, also called a fingerprint. For each key (and for backups) a separate pin directive must always be set.
- max-age: The max-age directive specifies the validity period of a pin in seconds. It tells the client for how long it should consider a public key to be a secure key. In the example used here, the listed pins are discarded after 30 days (2.592.000 seconds).
- includeSubDomains: The includeSubdomains statement is optional and requires no value. It signals to the client that the defined certification rules do not just apply only to the called-upon domain, but also to all subdomains belonging to the host.
- report-uri: If the report-uri directive is set, any pin validation errors are sent to the specified URL. This does not necessarily have to be on the same Internet domain as the contacted host, who is then informed about the failed setup attempts.
How does certificate pinning work on individual servers?
To make use of HPKP’s possibilities, you should first consider which public key(s) you want to ‘pin’. In principle, you can select any public key that is included in the certification chain, whether it is a root, intermediate, or your own server certificate. If one selects external certification bodies, however, one should keep in mind that all certificates on that site will subsequently be validated by the clients, and lead to successful pin validation.
If the server’s own server key is pinned, it can become a problem if the key becomes unstable or is lost due to a hardware defect. Since the clients have stored the pin at the first point of access for the specific validity period, they will not accept a new pin before that time frame expires. Your server would then be inaccessible to users. To prevent this scenario, the HPKP standard (RFC 7569) provides the additional use of a back-up pin. This is also delivered via the HTTP header and can be used to issue a new certificate for the corresponding domain in case of a problem. This option is referred to as a Certificate Signing Request (CSR).
Browsers like Mozilla Firefox and Google Chrome are based on the RFC 7469 standard and therefore ignore HPKP headers, or show error messages when only a single pin is set. For optimal HPKP browser support, it is therefore necessary to specify at least two valid public keys, or a backup pin, for the pin validation to work.
Calculating public key pins
If http public key pinning is working on your server, you need to have already configured HTTPS. Since at least two public keys need to be pinned, creating these pins is the first step that needs to be taken. The easiest way to calculate the hash values of existing public keys is the open source application openssl, which you can use via your system’s command line. RFC 7469 provides the standard command for X.509 certificates:
openssl x509 -noout -in certificate.pem -pubkey | \
openssl asn1parse -noout -inform pem -out public.key
openssl dgst -sha256 -binary public.key | openssl enc -base64
This is how you create the Base64 sequence for the public.key key for the sample certificate certificate.pem. This is outputted on the standard output and always ends on the equals sign („=“).
In the next step, you set up the Certificate Signing Request (here: backupcsr) for your back-up key (here: backup.key):
openssl genrsa -out backup.key 2048
openssl req -new -key backup.key -out backup.csr
Then use openssl to calculate the hash value of this key:
openssl req -noout -in backup.csr -pubkey | \
openssl asn1parse -noout -inform pem -out backup.key
openssl dgst -sha256 -binary backup.key | openssl enc -base64
Securing the backup pins
Since the HPKP back-up key is there to replace the default key in the event of a failure, it is useful to store it separately. The best option is to choose an external storage platform that you can reach at any time, from anywhere. Furthermore, the use of a password manager is recommended. Additionally, if you secure the Certificate Signing Request and the associated key in a separate database using this software, you are on the safe side – the backup key(s) are easily accessed and ready to use at a moments’ notice.
Criticism of public key pinning
Thanks to the ‘Trust on First Use’ approach, HPKP immediately sets out to create a connection with the client from its first point of contact. However, the first point of contact, in which the server transmits the pinned key, is not actually protected. Usually this small gap only leads to problems in isolated cases, and a large number of unintentional attacks on your websites’ SSL/TLS connections is almost impossible. The main criticism brought against public key spinning is the following attack scenario, which is only possible through pinning technology:
- An attacker gets access to your server.
- They install a new SSL/TLS certificate and then create their own set of keys.
- It also generates the appropriate hash value for the public key, and places this value in the appropriate area of the certificate pinning header, instead of your pins.
- Users or clients who call your website for the first time will receive the wrong PIN and subsequently cannot establish a secure connection to your server.
- If the attacker deletes the certificate from your server again, these users will be denied access to your page until the validity of the incorrect pin expires.
- In addition to inflicting damage through the resulting loss of traffic, the attacker also has the opportunity to demand money to unblock the incorrect certificate, and can blackmail you.
Even though this scenario is theoretically possible, it is by no means an argument against the use of HTTP public key pinning, because the attacker could set up the extension of the HTTP protocol as soon as he has access to the server. The problem ultimately proves just how important it is to protect your website against hacker attacks. If you are using pins, you should also make sure that your monitoring software has been alerted to promptly inform you when changes are made in the HPKP headers, to be able to intervene in time. Another possible approach to a solution on the clients’ part would be pin-reset mechanisms that regularly delete known ‘malicious’ pins.
Other negative criticisms mostly regard the low level of distribution and complexity associated with the configuration of public key pinning. The reasons for this are probably the fact that the standard is often poorly known or not known at all.