This post will explain how you can keep using HPKP while switching from commercial certificates to Letsencrypt certificates. In my previous post I already explained how to get a brand new certificate from Letsencrypt.org. If you’re working with HPKP, it’s critical that your public key doesn’t change when you’re installing a new certificate. The easiest solution is re-using an older Certificate Signing Request to request the new cert. If you still have the CSR, you can jump to “Let’s sign the CSR”.
Creating a new CSR
This section only applies if you don’t or can’t reuse the existing CSR. Since I had a need for extra Subject Alternative Names, let’s start to create a new CSR.
openssl req -new -key www.rivy.org.key -nodes -sha512 -subj "/CN=rivy.org" -reqexts SAN -out rivy.org.csr.der -outform der -config <( cat <<-EOF [req] distinguished_name = dn [dn] [SAN] subjectAltName=DNS:rivy.org,DNS:www.rivy.org,DNS:mail.rivy.org,DNS:webmail.rivy.org,DNS:imap.rivy.org EOF )
This single command writes the new CSR in DER format to rivy.org.csr.der. Note that I’m re-using the old key that was generated a long time ago. The public key corresponding to this private key is pinned in the HPKP header. For this reason, it’s critical that you don’t create a new key. If you do, HPKP (RFC7469) will kick in, and your browse will refuse to display the website.
Let’s sign the CSR
The previous post explains you how to install the letsencrypt client. Once installed, issue the next command to get your new CSR signed. Obviously you have to adapt these commands to your needs.
root@certserver:~/letsencrypt# ./letsencrypt-auto certonly -t --csr ../rivy.org.csr.der Updating letsencrypt and virtual environment dependencies....... Running with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt certonly -t --csr ../rivy.org.csr.der IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /root/letsencrypt/0001_chain.pem. Your cert will expire on 2016-03-10. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le root@certserver:~/letsencrypt#
Congratulations! You can find you’re new certificate here : /root/letsencrypt/0001_chain.pem. Note the file contains the issuer and the certificate. If I remove the issuer from the file and recalculate the PIN, it’s still exactly the same as previously.
rivy@certserver:~$ openssl x509 -in cert.crt -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64 writing RSA key VhFYptFYvVRv1KVvcUg3EfHvv15wkBFpRU332RNC2sM= rivy@asuslin:~$
The old version can be found in the previous post.