Secure trans­mis­sion channels are an important pre­requis­ite for working with digital data. It is of par­tic­u­lar im­port­ance to have a com­pletely secured path during a data trans­mis­sion when you are sending and receiving data packets remotely or while on the move. It is no accident that con­fid­en­tial in­form­a­tion is only trans­mit­ted via VPN or SSL/TLS con­nec­tions. En­ter­prises and fa­cil­it­ies with their own DNS servers and selected cer­ti­fic­a­tion bodies ensure that these protocol tech­no­lo­gies are almost un­touch­able. However, users who are active outside of these struc­tures are subject to the public DNS and site cer­ti­fic­ate hierarchy, which sig­ni­fic­antly increases the like­li­hood of a man-in-the-middle attack on their data. The main reason for the increased security risks are coun­ter­feit cer­ti­fic­ates issued by dubious or in­filt­rated cer­ti­fic­a­tion au­thor­it­ies. The user relies on the con­nec­tion and all their data being secure, while the trusting authority is para­dox­ic­ally re­spons­ible 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 con­nec­tions to a host. By doing this, an accessing client will find out which public keys they can trust when con­nect­ing to that host during the first contact. This is also referred to as a ‘Trust on First Use’ (‘Trust in first ap­plic­a­tion’). 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 con­nec­tion request is made, the client checks whether the cer­ti­fic­a­tion chain proposed for the SSL/TLS trans­mis­sion contains a public key, which was pre­vi­ously sent via HPKP. If this is not the case, for example if it was a fake cer­ti­fic­ate, an error message will be generated and the con­nec­tion will not be made. This veri­fic­a­tion process is also referred to as pin val­id­a­tion. 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 dir­ect­ives 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 con­clu­sions about the algorithm used for the en­cryp­tion. SHA256 is the only one possible to date. The hash value, which is within quotation marks, is a Base64 encoded string, also called a fin­ger­print. 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).
  • in­clude­Sub­Do­mains: The in­clude­Sub­do­mains statement is optional and requires no value. It signals to the client that the defined cer­ti­fic­a­tion rules do not just apply only to the called-upon domain, but also to all sub­do­mains belonging to the host.
  • report-uri: If the report-uri directive is set, any pin val­id­a­tion errors are sent to the specified URL. This does not ne­ces­sar­ily have to be on the same Internet domain as the contacted host, who is then informed about the failed setup attempts.

How does cer­ti­fic­ate pinning work on in­di­vidu­al servers?

To make use of HPKP’s pos­sib­il­it­ies, 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 cer­ti­fic­a­tion chain, whether it is a root, in­ter­me­di­ate, or your own server cer­ti­fic­ate. If one selects external cer­ti­fic­a­tion bodies, however, one should keep in mind that all cer­ti­fic­ates on that site will sub­sequently be validated by the clients, and lead to suc­cess­ful pin val­id­a­tion.

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 in­ac­cess­ible to users. To prevent this scenario, the HPKP standard (RFC 7569) provides the ad­di­tion­al use of a back-up pin. This is also delivered via the HTTP header and can be used to issue a new cer­ti­fic­ate for the cor­res­pond­ing domain in case of a problem. This option is referred to as a Cer­ti­fic­ate Signing Request (CSR).

Tip
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 val­id­a­tion to work.

Cal­cu­lat­ing public key pins

If http public key pinning is working on your server, you need to have already con­figured 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 ap­plic­a­tion openssl, which you can use via your system’s command line. RFC 7469 provides the standard command for X.509 cer­ti­fic­ates:

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 cer­ti­fic­ate cer­ti­fic­ate.pem. This is outputted on the standard output and always ends on the equals sign („=“).

In the next step, you set up the Cer­ti­fic­ate 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 sep­ar­ately. The best option is to choose an external storage platform that you can reach at any time, from anywhere. Fur­ther­more, the use of a password manager is re­com­men­ded. Ad­di­tion­ally, if you secure the Cer­ti­fic­ate Signing Request and the as­so­ci­ated 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 im­me­di­ately sets out to create a con­nec­tion 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 un­in­ten­tion­al attacks on your websites’ SSL/TLS con­nec­tions is almost im­possible. The main criticism brought against public key spinning is the following attack scenario, which is only possible through pinning tech­no­logy:

  1. An attacker gets access to your server.
  2. They install a new SSL/TLS cer­ti­fic­ate and then create their own set of keys.
  3. It also generates the ap­pro­pri­ate hash value for the public key, and places this value in the ap­pro­pri­ate area of the cer­ti­fic­ate pinning header, instead of your pins.
  4. Users or clients who call your website for the first time will receive the wrong PIN and sub­sequently cannot establish a secure con­nec­tion to your server.
  5. If the attacker deletes the cer­ti­fic­ate from your server again, these users will be denied access to your page until the validity of the incorrect pin expires.
  6. In addition to in­flict­ing damage through the resulting loss of traffic, the attacker also has the op­por­tun­ity to demand money to unblock the incorrect cer­ti­fic­ate, and can blackmail you.

Even though this scenario is the­or­et­ic­ally 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 ul­ti­mately 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 mon­it­or­ing 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 mech­an­isms that regularly delete known ‘malicious’ pins.

Other negative cri­ti­cisms mostly regard the low level of dis­tri­bu­tion and com­plex­ity as­so­ci­ated with the con­fig­ur­a­tion of public key pinning. The reasons for this are probably the fact that the standard is often poorly known or not known at all.

Go to Main Menu