I'm Ayesh Karunaratne, a freelance PHP/Drupal Web Developer and
a solo traveler.
I develop back-ends of awesome Drupal websites, built with performance, security and best practices in mind. Being a freelancer, I have plenty of time to travel. Currently living in Kandy, Sri Lanka, but the actual location may vary.
Sat, 2018-03-24 20:42
I was having a great tea (not coffee, that's important) yesterday, casually scrolling Twitter, passing over dozens of tweets from people who deleted their Facebook accounts (#deletefacebook), and came across this: Statement In Regard To DigiCert® Revocation & Symantec® Distrust.
I hope you remember the whole Trustico fiasco, that Trustico (a TLS certificate reseller) made DigiCert (the new owner of Symantec certificate authority) revoke ~23k certificates. To get a certificate from a CA or a reseller, you don't have to send the private key. However, Trustico had a tool that generated the private keys for customers and stored them. They still offered certificates over a regular CSR as well, and from what Trustico claims, they stored the private keys in a "cold storage".
Let me quote one point in Trustico's statement that I almost spilled my tea over and wanted to write this quick post:
As the only party other than Trustico® with access to the serial numbers for each certificate, only DigiCert® was able to undertake a match of the keys provided to issued certificates (by reference to serial numbers). Trustico® believes there were no security concerns for customers in what it did. Providing the private key and serial number would have been a security concern; the provision of one but not the other did not present a risk;
All other points of that post aside, I'd like to point out that this is not true. In fact, it's as easy as 1-2-3!
How to find certificates relating to a given private key
Every HTTPS certificate contains the public key that browser can use to establish a secure connection with the server. This public key can be easily derived from the private key. Once we have the public key, we can find certificates with a matching public key.
We use OpenSSL, because it's widely available. Refer to your relevant documentation if you want to do this in a different language
1. Get the public key
openssl rsa -in private-key.pem -outform DER -pubout -out public-key.der
We feed in (
private-key.pem file as the private key and take out the public key (
-pubout) in DER format (
-outform DER), and write it to a new file named
If you have a ECC key, replace the
rsa command above with
ec, for example
openssl rsa -in private-key.pem -outform DER -pubout -out public-key.der.
2. Calculate the SPKI hash
In each HTTPS certificate, there is an x509v3 field called
Subject Public Key Info. This field is simply the hash of the public key in DER format. Because we extracted the DER-formatted public key from the private key in above step, we can now calculate the SHA256 hash:
openssl dgst -sha256 public-key.der
You should see an output like this:
If we can find all certificates with a matching SPKI hash as same as above, we can find all certificates and their serial numbers.
3. Meet our savior, Certificate Transparency
Certificate Transparency is somewhat new project from Google, that enforces all Certificate Authorities to log every public certificate they issue to a log that they cannot modify later. Once this information is fed into a log, there is no way to update it, and tools like crt.sh and Censys make this information publicly available to search.
In the example above, the hash (
cd9bc7600534c1a352680859e47548dd59a604cd2e4380e4df58352d47c6be56) is from a test domain I use, and I have requested a few certificates from Let's Encrypt using the same private key (which produced the same SPKI hash). Lets Encrypt promptly logged the certificates they issued for me, and you can easily look them up from crt.sh results and Censys results.
Was it hard?
Gifs are from giphy.com of Petra from Jane the Virgin.