Public Key Pinning (PKP)
Last updated
Last updated
Pinning is the process of associating a host with their expected X509 (is a standard defining the format of public key certificate) certificate or public key. Once a certificate or public key is known or seen for a host, the certificate or public key is associated or 'pinned' to the host. If more than one certificate or public key is acceptable, then the program holds a pinset .In this case, the advertised identity must match one of the elements in the pinset.
HTTP Public Key Pinning (HPKP) is a security feature that tells a web client to associate a specific cryptographic public key with a certain web server to decrease the risk of MITM (man-in-the-middle) attacks with forged certificates.
Or
The HTTP Public Key Pinning (HPKP) security header, is used to tell a client to associate a particular public key to a specific web server. This security measure helps prevent man-in-the-middle (MITM) attacks in the event that an attacker compromises a certificate authority (CA) and starts issuing forged certificates. Public Key Pinning works in the following manner:
Upon the first visit to an HTTPS-enabled website, the client receives an HTTP header which contains information about the web server certificate’s public key.
Upon subsequent visits, the client expects the same public key to be present in the certificate chain.
If the previously known public key is not present, then the client should display a warning or send a report of a key mismatch.
To ensure the authenticity of a server's public key used in TLS sessions, this public key is wrapped into a X.509 certificate which is usually signed by a certificate authority (CA). Web clients such as browsers trust a lot of these CAs, which can all create certificates for arbitrary domain names. If an attacker is able to compromise a single CA, they can perform MITM attacks on various TLS connections. HPKP can circumvent this threat for the HTTPS protocol by telling the client which public key belongs to a certain web server.
With this method, the browser is able to tell if the public key from the origin server has changed and therefore avoid the risk of an attack.
Public Key Pins Directives
When enabling the HPKP on your web server (which we’ll explain how to do below), there are a few directives which need / can be defined. These include:
pin-sha256 (Mandatory) - Uses the SHA256 hash algorithm to specify the Base64 encoded Subject Public Key Information (SPKI) fingerprint.It is possible to specify multiple pins for different public keys. Some browsers might allow other hashing algorithms than SHA-256 in the future. See below on how to extract this information out of a certificate or key file.
max-age (Mandatory) - The amount of time (in seconds) for which the web client should recognize the server as a known pinned host or we can say that the time, in seconds, that the browser should remember that this site is only to be accessed using one of the defined keys.
includeSubDomains (Optional) - If this optional parameter is specified, this rule applies to all of the site's subdomains as well.
report-uri (Optional) - Provides you with the option to specify a URL for which any pin validation failures should be posted to.
Example of HPKP Header
In this example, pin-sha256="cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs="pins the server's public key used in production. The second pin declaration pin-sha256="M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=" also pins the backup key. max-age=5184000 tells the client to store this information for two months, which is a reasonable time limit according to the IETF RFC. This key pinning is also valid for all subdomains, which is told by the includeSubDomains declaration. Finally, report-uri="https://www.example.net/hpkp-report" explains where to report pin validation failures.
Now the question is why in the above example we are seeing two pin-sha256 values?
You can see that it specifies two pin-sha256 values, that is the pins of two public keys. One is the pin of any public key in your current certificate chain and the other is the pin of any public key not in your current certificate chain. The latter is a backup in case your certificate expires or has to be revoked.
It is definitely not obvious which public keys you should pin and what a good backup pin would be. The answer would be: it depends. You can pin one or all of the public keys in your certificate chain and that will work. The specification requires you to have at least two pins, so you must include the SPKI hash of another CA’s root certificate, another CA’s intermediate certificate (a different tier of your current CA would also work), or another leaf certificate. The only requirement is that this pin is not equal to the hash of any of the certificates in the current chain. The poor browser cannot tell whether you gave it a valid and useful backup pin so it will happily accept random values too.
How To Enable Public Key Pins
Depending upon which web server you are using, the process for enabling HPKP will be slightly different. However, each snippet below will ultimately render the same outcome - add the Public-Key-Pins header to your HTTP responses. The snippets required for Apache and Nginx web servers are each outlined below.
Apache
The following snippet can be added to your Apache web server’s configuration file. In order for this to work, you will need to have the mod_headers module enabled.
The following is an example for Apache users with the placeholders filled in.
Nginx
The following snippet can be added to your Nginx server’s configuration file. This requires that you have the ngx_http_headers_module enabled.
With the placeholders filled in, the snippet should look similar to: