Public key pinning is a certificate chain must contain a public key in a whitelist, which means that only the certificate issuing authority (CA) that is listed on the whitelist can issue a certificate for a domain *.example.com, not any CA stored in your browser can be issued for them. This article describes the background of this mechanism and provides examples of configurations on Apache, LIGHTTPD, and NGINX.
HTTP Public key fixed extension
Use the bank you use as an example, and it has been using CA company A to issue a certificate for it. But under the current certificate system, CA B, CA C, and the NSA CA can create certificates for your bank, and your browser will accept them without misgiving because these are the root CAs you trust.
If your bank implements the HPKP and fixed their first intermediate certificate (from CA company A), the browser will not accept certificates from CA company B and CA company C, even if they have a valid chain of trust. HPKP also allows your browser to report such violations to the bank so that the bank knows it was attacked by a forged certificate.
The HTTP public key fixed extension is a public key fixed standard that has been developed since 2011 for the HTTP User agent (ie, the browser). It is launched by Google, and even the fixed mechanism implemented in Chrome can use a fixed list of manually maintained public key web sites that contain the public key signatures of several fixed sites. (LCTT: Chrome and FireFox 32 and later versions both support public key retention mechanisms and use built-in, manually maintained public key fixed list data, which is updated with browser software updates, including several large sites.) Currently, only Chrome 38+ supports passing public-key fixed information via HTTP response headers. )
Here are a few features of HPKP:
- The HPKP is set at the HTTP level, using the Public-key-pins (PKP) response header.
- The retention period for this rule is set by the Max-age parameter in seconds.
- The PKP response header can only be used in the correct secure encrypted communication.
- If more than one such response header appears, only the first one is processed.
- A fixed mechanism can be extended to a subdomain using the Includesubdomains parameter.
- When a new PKP response header is received, it overwrites the previously stored public key retention and metadata.
- Public key fixing is generated using a hashing algorithm, which is actually a "subject public key information (SKPI)" fingerprint.
This article will first introduce some of the principles of HPKP work, and then we'll show you how to get the fingerprint you need and configure it to the Web server.
SPKI Fingerprint-theory
In general, hashing a certificate is an obvious solution, but it's actually wrong. This cannot be done because the CA certificate can be continuously renewed: the same public key, subject name can correspond to multiple certificates, and these certificates have different extension or expiration times. When the browser builds the certificate chain in the certificate pool from the bottom up, another version of the certificate may replace the certificate that matches what you originally expected.
For example, STARTSSL has two root certificates: one is signed by SHA1, and the other is SHA256. If you want to hold Startssl as your CA, which certificate should you use? You may be able to use these two, but if I don't tell you, how do you know there's a root certificate?
Conversely, a hash of the public key does not have this problem:
The browser assumes that the child certificate is fixed: It is always the starting point for the certificate chain. A child certificate must carry a signature that is a valid signature from its parent certificate that is specifically issued for this certificate. This means that the public key of the parent certificate is fixed relative to the child certificate. So it can be inferred that the public key chain is fixed.
The only problem is that you can't fix it on a cross certified root certificate. For example, GoDaddy's root certificate is Valicert signature, this is to let those who can not identify GoDaddy root certificate of old customers can trust their certificates. However, you can not be fixed to the Valicert, because the new customer found in the certificate chain GoDaddy certificate will stop tracing (LCTT: So I can not find the fixed information).
In addition, we hash the Subjectpublickeyinfo (SPKI) instead of the public key bit string. The SPKI includes the public key type, the public key itself and its related parameters. This is important because if you hash the public key, it can cause a misinterpretation attack to occur. For a Diffie-hellman public key: If only the public key is hashed, not the full SPKI, the attacker can use the same public key to interpret it as another group. Similarly, it is possible to force an RSA key to be interpreted as a DSA key, and so on.
Where is it fixed?
Where should you be fixed? Fixing your own public key is not the best way to do it. Your key may be changed or revoked. You may use multiple certificates, and the key changes when you rotate the certificate frequently. Perhaps the certificate was revoked because the server was compromised.
The easiest but not too secure method is to fix the first intermediate CA certificate. The certificate is signed on top of your site certificate, so the public key of the CA that issued the certificate must be on the certificate chain.
In this way you can update your certificate from the same CA without worrying about the incorrect fixed information. If the CA issues a different root certificate, you may encounter some problems that are not a good solution. However, you can mitigate the impact of this problem by doing the following:
Request an alternate certificate from a different CA and fix the backup.
The RFC says you need to do at least two fixed. One is on the certificate chain used by the current connection, and the other is backed up.
The other fix is to back up the public key, which can be a skpi fingerprint from another CA that gives you a certificate.
A more secure way to do this is to create at least three separate public keys in advance (using OpenSSL, see this page for Javascript OpenSSL command generators), and two of them back to a secure location, offline storage, and not online.
Create SPKI fingerprints for these three certificates and fix them, and then use only the first one as the current certificate. When needed, you can use one of the backup keys. But you need to have the CA sign you up to generate the certificate, which may take a few days, depending on how your CA works.
This is fine for HPKP, because we're using the SPKI hash of the public key, not the certificate. Failure or a different CA signature chain does not affect.
If you generate and securely store at least three separate keys in the way described above, and fix them, you can prevent your CA from revoking your Web site certificate and issuing a fake certificate with a problem.
SPKI fingerprints .
You can use the following OpenSSL command to generate a SPKI fingerprint, which appears in the draft RFC:
Copy Code code as follows:
OpenSSL x509-noout-in Certificate.pem-pubkey | \
OpenSSL asn1parse-noout-inform pem-out Public.key;
OpenSSL dgst-sha256-binary Public.key | OpenSSL enc-base64
Results:
Copy Code code as follows:
klo23nt2ehfdxcfx3ehtdresmz3asj1muo+4aidjiuy=
The Certificate.pem file entered above is the first certificate in the certificate chain of this site (https://raymii.org). (At the time of this writing, COMODO RSA Domain Validation Secure Server CA, serial number 2b:2e:6e:ea:d9:75:36:6c:14:8a:6e:db:a3:7c:8c:07).
You also need to generate fingerprints for your other two backup public keys as well.
Fault
When writing this article (2015/1), the only browser that supports HPKP (Chrome) has a serious problem: Chrome is not able to distinguish between max-age and Includesubdomains parameters in the HSTs and HPKP response headers. In other words, if your hsts and HPKP set different max-age and includesubdomains parameters, they would mess up with each other. For more information on this failure see: https://code.google.com/p/chromium/issues/detail?id=444511. Thank Scott Helme (https://scotthelme.co.uk) for discovering and telling me about this Chromium project.
WEB Server Configuration
Below you can see the three main Web server configuration methods. This is just an HTTP response header, and most WEB servers can set it up. It only needs to be set up on the HTTPS Web site.
The following example is fixed to the COMODO RSA Domain Validation Secure Server CA and the backup COMODO Positivessl CA for a 30-day expiration period, including all subdomains.
Apache
Edit your Apache configuration file (such as/etc/apache2/sites-enabled/website.conf or/etc/apache2/httpd.conf) and add the following line to your virtualhost:
Copy Code code as follows:
# if necessary, load the headers module.
LoadModule Headers_module modules/mod_headers.so
Header set Public-key-pins "pin-sha256=\" klo23nt2ehfdxcfx3ehtdresmz3asj1muo+4aidjiuy=\ "; Pin-sha256=\ "633lt352pkrxbowf4xsea1m517scpd3l5f79xmd9r9q=\"; max-age=2592000; Includesubdomains "
Lighttpd
LIGHTTPD simpler, add the following lines to your LIGHTTPD configuration file (such as/etc/lighttpd/lighttpd.conf):
Copy Code code as follows:
Server.modules + + ("mod_setenv")
$HTTP ["scheme"] = = "https" {
Setenv.add-response-header = ("Public-key-pins" => "pin-sha256=\" klo23nt2ehfdxcfx3ehtdresmz3asj1muo+4aidjiuy=\ " ; Pin-sha256=\ "633lt352pkrxbowf4xsea1m517scpd3l5f79xmd9r9q=\"; max-age=2592000; Includesubdomains ")
}
Nginx
NGINX configuration is shorter. Add the following line to the server block of your HTTPS configuration:
Add_header public-key-pins ' pin-sha256= ' klo23nt2ehfdxcfx3ehtdresmz3asj1muo+4aidjiuy= '; Pin-sha256= "633lt352pkrxbowf4xsea1m517scpd3l5f79xmd9r9q="; max-age=2592000; Includesubdomains ';
Reporting capabilities
The HPKP reporting feature allows browsers to report any offending to you.
If you add an additional report-uri= "Http://example.org/hpkp-report" parameter to the response header and use the URI to process the received data, the client sends a report to you when the violation is found. This report is posted to the Report-uri you specify and is formatted in JSON format similar to the following:
Copy Code code as follows:
{
"Date-time": "2014-12-26t11:52:10z",
"hostname": "www.example.org",
"Port": 443,
"Effective-expiration-date": "2014-12-31t12:59:59",
"Include-subdomains": true,
"Served-certificate-chain": [
"-----begincertificate-----\nmiiauyg[...] tqu0ckvdnx\n-----endcertificate-----"
],
"Validated-certificate-chain": [
"-----begincertificate-----\nebdccygawiba[...] px4wecnx\n-----endcertificate-----"
],
"Known-pins": [
"Pin-sha256=\" Duezru9zoecb901md727xwltnsj0e6qzgk\ "",
"Pin-sha256=\" E9cqvkb9+xz9indbd+2erqozqbq2yxlyc\ ""
]
}
Not mandatory, reporting only
HPKP can also be set to not mandatory, you can use Public-key-pins-report-only to send only the offending report to you.
This allows you to HPKP when the site is inaccessible or incorrectly configured, and then you can change the response header to Public-key-pins to force the fix.