HTTP Public Key Pinning (HPKP)
HPKP is another security mechanism that uses an HTTP header as protection against impersonation attacks with fraudulently issued certificates. To enable it on the server side, it’s required to add a special directive that contains hashes of public keys (pins) contained within certificates the server supplies via Certificate message. When browser with HPKP support receives such a header, it validates pins comparing them with the certificate chain. If validation is successful, it associates the website with received pins. Since then, the connection should result in a non-recoverable error in case of pin validation failure during further connections.
- Open IIS Manager and select the website you would like to apply HPKP for.
- Double-click on the HTTP Response Headers shortcut:
- Click on Add in the right side of Actions menu
- Enter Public-Key-Pins in the Name field
- Calculate SPKI digest using SHA-256 hash function with Openssl or using the online calculator
- Enter the string as below in the Value field:
pin-sha256=”SPKI_digest#1"; pin-sha256="SPKI_digest#2"; max-age=31536000
- You need to replace SPKI_digest#1 with the SPKI digest (pin) computed using SHA-256 over one of certificates the server currently sends during SSL/TLS.
- You need to replace SPKI_digest#2 with the SPKI digest (pin) computed using SHA-256 over one of certificates in your backup certificate chains.
Backup pin is an obligatory requirement.
Max-age directive specifies time (in seconds) during which after reception of HPKP header field a client application treats the host (from whom the message was received) as a known HPKP host. In simple words, it’s time a browser should keep “HPKP” cookies and perform HPKP validation using pins received in the header initially.
pin-sha256="klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY="; pin-sha256="kb6xLprt35abNnSn74my4Dkfya9arbk5zN5a60YzuqE="; max-age=31536000
- Optionally you can add includeSubDomains in Value field if you would like to apply HPKP policy for subdomains of your domain name as well as for the main domain name.
If you would like to include it, includeSubDomains directive should be added in the end of the string and delimited with a semicolon:
pin-sha256="klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY="; pin-sha256="kb6xLprt35abNnSn74my4Dkfya9arbk5zN5a60YzuqE="; max-age=31536000; includeSubDomains
- Click OK.
Starting from version 69, Google Chrome browser deprecated HTTP-Based Public Key Pinning mechanism preferring Expect-CT