web-dev-qa-db-fra.com

Déterminer si la clé privée appartient au certificat?

Étant donné un certificat¹ et un fichier de clé privée², comment puis-je déterminer si la clé publique du certificat correspond à la clé privée?

Ma pensée initiale était de simplement crypter du texte avec la clé publique sur le certificat et d'essayer de le décrypter avec la clé privée. Si ça va, nous avons un gagnant. Je ne peux pas comprendre comment faire cela avec OpenSSL.

Alternativement, si je pouvais générer la clé publique à partir de la clé privée, je pourrais simplement comparer leurs empreintes digitales. SSH semble avoir une commande pour cela (ssh-keygen -y -f my_key > my_key.pub), mais les hachages ne correspondent pas. (Je suis presque certain que j'ai la clé correspondant au certificat, car le serveur Web le sert, mais j'aimerais un moyen plus simple de faire tourner un serveur pour vérifier.)

¹ un fichier .crt, au format x509, je pense. OpenSSL peut le lire avec openssl x509 -text -in that_cert.crt
² Une clé privée RSA

41
Thanatos

Je vais supposer que vous avez ssl.crt et ssl.key dans votre répertoire actuel.

Si vous voulez voir ce qui est dans votre certificat, c'est

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

Deux des éléments ici seront le module et l'exposant de clé publique RSA (en hexadécimal).

Si vous voulez voir ce qu'il y a dans votre clé privée, c'est

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

Notez que la clé publique est généralement là (au moins le module doit être là pour que la clé privée fonctionne, et l'exposant public est généralement 65537 ou 3). Vous pouvez donc simplement vérifier si le module et l'exposant public correspondent. Certes, si vous voulez vérifier que la clé privée est réellement valide (c'est-à-dire que d et e sont des exposants RSA valides pour le module m), vous devrez exécuter

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

EDIT (2018):Veuillez noter que si vous vérifiez qu'une clé privée provenant d'une source non fiable correspond à un certificat, vous DEVEZ VÉRIFIER que la clé privée est valide. Voir ici pour un exemple où le fait de ne pas vérifier la validité d'une clé privée "divulguée" conduit à une CA qui révoque incorrectement un certificat. Vous pouvez ignorer cette étape si vous savez que vous avez valablement généré la paire de clés.

Maintenant, vous pouvez simplement générer la clé publique à partir du certificat et de la clé privée, puis utiliser diff pour vérifier qu'elles ne diffèrent pas:

# 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

Ou comme une ligne qui ne crée pas de fichiers (en utilisant substitution de processus ):

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

Si les clés correspondent, diff ne devrait rien renvoyer. (Vous verrez probablement la sortie "écriture de la clé RSA" vers stderr à partir de la deuxième commande).

Notez que votre serveur Web se plaindrait probablement fortement si le certificat et la clé privée ne correspondaient pas. Par exemple, avec nginx utilisant la mauvaise clé (même taille, même exposant public, mais la clé de l'année dernière) pour le certificat nginx utilise:

# 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
52
dr jimbob

La réponse acceptée est correcte, mais elle ne fonctionne que pour les clés RSA.

Au moins depuis openssl 1.1.1, il est possible de tester la validité de tous les types de clés privées et voici une ligne qui fonctionne pour toutes sortes de clés prises en charge par openssl

 cmp <(openssl x509 -pubkey -in certificate.pem -noout) <(openssl pkey -check -pubout -in private-key.pem -outform PEM)

Il renverra "vrai" si et seulement si la clé privée correspond à la clé publique dans le certificat.

11
Manish