Configure HKPK on Apache

What is HKPK

The Wikipedia explanation is the following:

HTTP Public Key Pinning (HPKP),[1] 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

Apache implementation

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


  • Calculate the backup key hashes
    openssl req -noout -in test_backup.csr -pubkey | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64


  • 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

Leave a Reply

Your email address will not be published. Required fields are marked *