What is HKPK
The Wikipedia explanation is the following:
HTTP Public Key Pinning (HPKP), sometimes incorrectly known as certificate pinning, is a security mechanism which allows HTTPS websites to resist impersonation by attackers using mis-issued or otherwise fraudulent certificates.
For example, attackers might compromise a certificate authority, and then mis-issue certificates for a web origin. To combat this risk, the HTTPS web server serves a list of “pinned” public key hashes; on subsequent connections clients expect that server to use one or more of those public keys in its certificate chain
How it works
Also a good explanation from the same Wikipedia article:
The server communicates the HPKP policy to the user agent via an HTTP response header field named Public-Key-Pins (or Public-Key-Pins-Report-Only for reporting-only purposes).
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 (and at least one backup key) in pin-sha256 directives, and a period of time during which the user agent shall enforce public key pinning in max-age directive, optional includeSubDomains directive to include all subdomains (of the domain that sent the header) in pinning policy and 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 least one backup key must be pinned, in case the current pinned key needs to be replaced. The HPKP is not valid without this backup key (a backup key is defined as a public key not present in the current certificate chain).
Read full explanation here
As shown above, to implement HKPK on Apache, you will need your official public key and a backup key.
- Create your primary key / primary request
openssl req -newkey rsa:2048 -keyout test_primary.key -out test_primary.csr
- Create your backup key / backup request
openssl req -newkey rsa:2048 -keyout test_backup.key -out test_backup.csr
- Calculate the primary key hashes
openssl req -noout -in test_primary.csr -pubkey | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64
Output12writing RSA keySCvRhAz86T1PHyw5yglAVaXe2Pb4P0HNoXh+FAo5l9A=
- Calculate the backup key hashes
openssl req -noout -in test_backup.csr -pubkey | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64
Output12writing RSA keyVDorIRMWWYxBRGAfRIeQtzjCd2EvaU10aZ69RTkXMXo=
- Edit your Apache virtual host and add the following line
Header always set Public-Key-Pins "pin-sha256=\"SCvRhAz86T1PHyw5yglAVaXe2Pb4P0HNoXh+FAo5l9A=\"; pin-sha256=\"VDorIRMWWYxBRGAfRIeQtzjCd2EvaU10aZ69RTkXMXo=\"; max-age=5184000"
- Restart Apache
systemctl restart apache2