6

Someone gave me a certificate and a couple of private/public keys, and said, "tell me which private key matches the certificate." How do I do that?

The certificate is in PKCS #7 format and starts with:

-----BEGIN CERTIFICATE-----

The keys all look different. Some of them are actually public keys - some I'm not sure. They have different extensions and begin with different strings, like these for example:

-----BEGIN PRIVATE KEY-----
-----BEGIN EC PARAMETERS-----
-----BEGIN RSA PRIVATE KEY-----

Any help? I think I can use the openssl commandline tool.

3

3 Answers 3

7

Based on commands given in Verifying that a Private Key Matches a Certificate (originally from The Apache SSL FAQ) it's possible to build a small bash script that iterates through all *.key files in the folder and compares the modulus portion of the certificate with every key at once.

My findkey.sh takes the certificate's filename as a command line argument & prints the matches.

#!/bin/bash
cert=$1
crthash=$(openssl x509 -noout -modulus -in "$cert" | openssl md5)
echo $cert $crthash

for file in *.key; do
    [ -e "$file" ] || continue
    keyhash=$(openssl rsa -noout -modulus -in "$file" | openssl md5)
    if [ "$keyhash" = "$crthash" ]
    then
        keytest==$(openssl rsa -in "$file" -check -noout)
        echo $file $keyhash $keytest
    fi
done

I created some key pairs testN.key / testN.crt and tested my script, which seems to do the job:

./findkey.sh test4.crt
test4.crt (stdin)= 8e30eac60ff8d3c5b1c9bee7e79774bb
test4.key (stdin)= 8e30eac60ff8d3c5b1c9bee7e79774bb =RSA key ok

It doesn't matter if there's some certificates (or certificate requests) among the keys, because even if named incorrectly as *.key the openssl rsa -modulus would give unable to load Private Key error instead of the modulus for the certificate. In addition, the end of the line tells whether the key is consistent, to prevent fake private keys. You only need this script & OpenSSL installed.

5
  • By removing | openssl md5 from both commands you can modify this to compare the whole modulus instead of the MD5 hashes, but there's no difference in practice, and visual verification is easier from the hashes. Apr 24, 2018 at 8:18
  • 1
    Interestingly, according to that "fake private keys" blog, (at least at the time it was written) StackExchange was the only place on the 'net to describe a proper way of checking a private key. The list of places that got it wrong is quite worrying!
    – TripeHound
    Apr 24, 2018 at 10:25
  • 1
    In this situation, verification would not be even completely relevant because the source of the keys is likely internal, making the risk of counterfeiting small. However, this is Security Stack Exchange, so better be complete; someone may use this script for other purposes. Apr 24, 2018 at 11:13
  • 1
    True, in this case "fake" certificates are probably not a problem. It just seemed worth pointing out that of all the "how to check a certificate" instructions kicking around -- including from people who should have known better -- the only one to get it right was on Security Stack Exchange (with yours, now at least two).
    – TripeHound
    Apr 24, 2018 at 11:18
  • 1
    Thanks for the information @EsaJokinen. However I think this will only work for RSA keys, not ECDSA or ECC (or other types).
    – Ev.
    Apr 25, 2018 at 23:49
0

You may use a certificate key matcher tool to check whether your private key matches the certificate like the following one:

https://www.sslshopper.com/certificate-key-matcher.html

Moreover if you want to use the openssl commandline tool, the followings would be a suggested for reading:

2
  • 6
    Using ANY website that processes the key server-side is highly insecure. Even the site itself points this out: "for complete security, we recommend that you manually check the public key hash of the private key on your server using the OpenSSL commands above". Apr 24, 2018 at 6:25
  • Thanks for the answer @mahmudKabir . I'm a bit nervous to use the site as mentioned above, and I'm having trouble with the command line tools. I think the problem is that I don't know what format the keys are in, so I need to figure out how to determine that
    – Ev.
    Apr 24, 2018 at 6:38
0

The easiest way to match is to simply generate a signature with the private key and then try all the certificates to verify the signature. If this fails because the certificate is only for encrypting then you could either override that or you could encrypt something and then use the private key to decrypt.

If any of these actions succeed then you know you've got a match; these operations can by definition only succeed with the right key, regardless of the algorithm used. Note that you should make sure that you don't sign/encrypt anything sensitive of course. Better throw away the result in the end.

You need to be sure that you use the correct operation for the scheme used during decryption / verification (but I guess that's a given). ECDSA can only be used for signature generation / signing, by the way.

The only time that above is not a good idea is when you've got legally binding signatures or a counter for the use of the private key usage (e.g. in a hardware device).


Note that for proper encryption / verification you need to trust the public key. That means that you need to validate the certificate and verify the signature over the certificate as well.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .