Previously, we have talked about HTTP Public Key Pinning (HPKP). HPKP is a security feature is to prevent fraud TLS certificates. Here Are the Steps to Enable HTTP Public Key Pinning (HPKP) on Nginx. We are using Ubuntu 16.04 LTS and latest version of Nginx. Reader will need to adjust some come commands for non deb GNU/Linux distro.
What is HTTP Public Key Pinning (HPKP) and Why We Need?
If a bad steal the CA’s private key and browser trusts the certificate, the bad can forge valid certificates for any website. So performing a man-in-the-middle (MITM) attack against every website is not impossible. HTTP Public Key Pinning (HPKP) significantly decrease the risk of MITM by allowing website operators to limit the certificates that can participate in their website’s chain of trust and to detect in-progress attacks.
HTTP Public Key Pinning (HPKP) is a security measure for the HTTPS websites to nullify the chance of impersonation by script-kiddies using fraudulent certificates. Nginx web server will serve a list of public key hashes by header, client browser will expect that the server will use one or more of those public keys in its certificate chain. HTTP Public Key Pinning (HPKP) is standardized in RFC 7469. The Nginx Server will communicate to the HPKP policy to the user agent via an HTTP response header field named Public-Key-Pins or Public-Key-Pins-Report-Only. The HPKP policy specifies :
- hashes of the subject public key info of one of the certificates in the website’s authentic X.509 public key certificate chain
- at least one backup key
- a time duration which the user agent shall enforce public key pinning via max-age directive
- optional includeSubDomains directive to include all subdomains
- optional report-uri directive with URL where to send pinning violation reports.
At least one of the public keys of the certificates in the certificate chain needs to match a pinned public key in order for the chain to be considered valid by the user agent. At the time of publishing this guide, RFC 7469 allowed hash algorithm SHA-256. Hashes for HPKP policy can be generated by shell commands or third-party tools. The HTTP Public Key Pinning (HPKP) will not be valid without minimum one backup key. Report URI should not be on same domain.
Steps to Enable HTTP Public Key Pinning (HPKP) : Nginx
Users can register for report-uri.io‘s free service. You will get few of the needed stuffs :
- HTTP Public Key Pinning keys
- Reporting URI service
- Testing tools
Technically, we can generate it with this command, where our web server’s certificate is
www.thecustomizewindows.com.csr and we are at that directory :
openssl req -inform pem -pubkey -noout < www.thecustomizewindows.com.csr | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
You will get something as output like :
That is “KEY”.
More detailed steps are written on our old guide. report.io service does the work. We need minimum another TLS certificate or any other web server specific certificate to run the above command to get another “KEY”. The second one is “Backup Key”. Further information can be found on :
Normally, users use
/etc/nginx/sites-available/default file for Nginx we save site configuration. We have to add in this format for Nginx with add_header directive :
add_header Public-Key-Pins 'pin-sha256="Paste-first"; pin-sha256="Paste-second"; report-uri="https://9fe34499a39b5130fa25da9e401e04a0.report-uri.io/r/default/hpkp/enforce" max-age=5184000; includeSubDomains';
Run nginx config test and restart Nginx. Test with SSL Lab’s test. You can test our header :
curl -I https://thecustomizewindows.com | grep Public-Key-Pins
You’ll get the response :
Public-Key-Pins: pin-sha256="snqzW9Bwdb/++vjcA36+kbP/qaVMmnB9ckuI3qAkihQ="; pin-sha256="BJKSF/6L2QXz4xK6MVj2RTiyPlFzQx3NcpuxnuqdABk="; report-uri="https://9fe34499a39b5130fa25da9e401e04a0.report-uri.io/r/default/hpkp/enforce"; max-age=5184000; includeSubDomains