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.

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


EDIT (2018): Please note if you are checking that a private key coming from an untrusted source corresponds with a certificate, you MUST CHECK that the private key is valid.  See here for an example where not checking the validity of a "leaked" private key lead to a CA improperly revoking a certificate.  You may skip this step if you know you validly generated the keypair.

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

