There was obviously a lot of confusion about how HTTP Public Key Pinning (HPKP) worked. In the middle of the incredibly hectic process of running a major conference, it’s the last kind of issue anybody wants to have to deal with. In today’s article, I’d like to explain how to issue a new certificate that uses the keys of the old expired SSL certificate.
Getting Back To Normal
The truth is that there was no surefire way out of this without some users still seeing issues, but here are the steps I helped Smashing Magazine to take to get back to a normal situation.
Further Reading on SmashingMag:
- HTTP/2: A Guide For Web Designers And Developers
- World Wide Web, Not Wealthy Western Web’“)
- HTTPS Everywhere With Nginx, Varnish And Apache
- A Look At The Modern WordPress Server Stack
1. Procure the original private key for the expired certificate
At first, their web host claimed that the copy they had required a password that they were not aware of. Fortunately, you don’t just use the key when generating the certificate. The web server doing the TLS termination also needs a copy of the private key, and on servers the private key is rarely password protected since this requires manually typing the password every time the server is restarted for any reason.
We got the web host to find the old key on the web server and with that key in hand we were ready for the next step.
2. Add the old key to the new public key pinning headers
Running this OpenSSL command generates the Base64 encoded digest of the key that will tell browsers to pin it:
openssl rsa -in my-key-file.key -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64
With this digest in hand, I told Smashing Magazine to update their headers to:
Public-Key-Pins: pin-sha256="35L+K6PY5ynTu15SYPrT8KXp5TRH8kzP46mYLpv9k30="; pin-sha256="8RoC2kEF47SCVwX8Er+UBJ44pDfDZY6Ku5mm9bSXT3o="; pin-sha256="78j8kS82YGC1jbX4Qeavl9ps+ZCzb132wCvAY7AxTMw="; pin-sha256="GQGOWh/khWzFKzDO9wUVtRkHO7BJjPfzd0UVDhF+LxM="; max-age=86400; includeSubDomains
Two changes here — I brought the
max-age down to one day instead of a full year. Having a
max-age of a year for public key pinning means that losing the private keys used to generate the certificates can permanently shut down your site completely for a year. Bad idea!
The other change was to include the digest for the old certificate. We needed to do this because a group of visitors that had visited the site after the new certificate went live, but didn’t have the old certificate pinned, would now get the same SSL errors if Smashing simply switched certificates again. So we pushed this out and gave them a few hours to make a second visit and get the old digest as well.
3. Generate a new certificate from the old key
The penultimate step was to generate a new certificate from the old key. To generate an SSL certificate you first need a “Certificate Request.” You’ll never want to share your private key with the certificate provider. Instead, you use it to sign a certificate request like this:
openssl req -new -sha256 -key my-key-file.key -out my-certificate-request.csr
During the certificate request generation, you’ll be asked about various questions. The most important is the “Common Name” of the certificate which determines what domain it will be valid for.
Once you have a CSR, you can use it to order a certificate from any provider.
4. Change the certificate
Armed with the new certificate signed with the old key, we could finally put a certificate live that would work again for the vast majority of visitors. Some unlucky souls may have visited while the new certificate with the new key pinning header was live, without coming back while both key pining headers were in place. These will simply be unable to access Smashing Magazine until they clear their key pinning cache or use another browser.
After losing out on thousands of visitors, Smashing Magazine was back online and the people behind it could go back to focusing on a fantastic conference in Barcelona.
(vf, ms, il)