Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

Given a certificate¹ and a private key file², how can I determine if the public key on the certificate matches the private key?

My initial thought was to simply encrypt some text with the public key on the cert, and attempt to decrypt it with the private key. If it roundtrips, we've got a winner. I just can't figure out how to do this with OpenSSL.

Alternatively, if I could generate the public key from the private key, I could just compare their fingerprints. SSH seems to have a command for this (ssh-keygen -y -f my_key > my_key.pub), but the hashes don't match. (I'm nearly certain I have the key corresponding to the cert, as the webserver is serving with it, but I'd like an easier way that spinning up a server to check.)

¹ a .crt file, in x509 format, I think. OpenSSL can read it with openssl x509 -text -in that_cert.crt
² An RSA private key

share|improve this question

1 Answer 1

I'm going to assume you have ssl.crt and ssl.key in your current directory.

If you want to see what's in your certificate it's

# openssl x509 -in ssl.crt -text -noout

Two of the things in here will be the RSA public Key's Modulus and Exponent (in hex).

If you want to see what's in your private key it's

# openssl rsa -in ssl.key -text -noout

Note the public key is usually in there (at the very least the modulus is required to be in there for the private key to work, and the public exponent is usually 65537 or 3). So you can simply check if the modulus and public exponent match. Granted, if you want to check that the private key is actually valid (that is d and e are valid RSA exponents for the modulus m), you would need to run

# openssl rsa -check -in ssl.key -noout

Now you can simply generate the public key from both the certificate and the private key and then use diff to check that they don't differ:

# openssl x509 -in ssl.crt -pubkey -noout > from_crt.pub
# openssl rsa -in ssl.key -pubout > from_key.pub
# diff from_crt.pub from_key.pub

Or as a one liner that doesn't create files (using process substitution):

# diff  <(openssl x509 -in ssl.crt -pubkey -noout) <(openssl rsa -in ssl.key -pubout)

If the keys match, diff shouldn't return anything. (You probably will see "writing RSA key" output to stderr from the second command).

Note your webserver probably would loudly complain if the certificate and private key didn't match. E.g., with nginx using the wrong key (same size, same public exponent, but last year's key) for the certificate nginx is using:

# sudo /etc/init.d/nginx restart
* Restarting nginx nginx                                                                                         
nginx: [emerg] SSL_CTX_use_PrivateKey_file("/etc/nginx/ssl/private/wrong_key.key") failed 
(SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
nginx: configuration file /etc/nginx/nginx.conf test failed
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.