« key values mismatch » : quand certificat et clé ne vont pas ensemble

Après l’installation d’un nouveau certificat, le serveur web refuse de démarrer. Le message paraît obscur, mais la cause est presque toujours l’une de ces quatre.

À quoi ressemble l’erreur

# nginx (OpenSSL 3)
SSL_CTX_use_PrivateKey("/etc/ssl/private/server.key") failed
(SSL: error:05800074:x509 certificate routines::key values mismatch)

# Apache
AH02565: Certificate and private key www.exemple.fr:443:0 from
/etc/ssl/certs/server.crt and /etc/ssl/private/server.key do not match

# HAProxy
inconsistencies between private key and certificate loaded from PEM file

Sous Windows/IIS, le même problème se présente autrement : la liaison du certificat échoue avec « A specified logon session does not exist » (message de Windows en anglais), ou le certificat n’affiche pas d’icône de clé dans la console.

Ce que vérifie le serveur

Un certificat contient la clé publique. Le serveur détient la clé privée correspondante. Au démarrage, il vérifie que les deux forment une paire. Si ce n’est pas le cas, il refuse de servir, car aucun client ne pourrait établir la connexion.

Les quatre causes les plus fréquentes

1. Le certificat appartient à un autre CSR

Le grand classique : un nouveau CSR avec une nouvelle clé a été créé pour le renouvellement, mais c’est l’ancienne clé qui a été installée. Ou le CSR a été créé sur un autre serveur ou par un collègue.

2. Mauvais ordre dans le fichier de certificats

nginx et HAProxy comparent la clé avec le premier certificat du fichier. Si l’intermédiaire arrive en premier parce que les fichiers ont été concaténés dans le mauvais ordre, la clé ne peut pas correspondre.

# correct : d’abord le certificat serveur, puis les intermédiaires
cat server.crt intermediate.crt > fullchain.pem

3. La configuration pointe vers le mauvais fichier

Une faute de frappe dans le chemin, un lien symbolique vers un ancien fichier, ou certificat et clé inversés dans la configuration.

4. Windows : certificat sans clé privée

Si un fichier .cer a été importé alors que le CSR a été créé sur une autre machine, la clé manque. Si le CSR a été créé sur le même serveur, le lien avec la clé peut souvent être rétabli :

certutil -repairstore my <numéro de série du certificat>

Comment savoir ce qui va ensemble

Le plus rapide est la correspondance de clé : dépose le certificat, la clé et le CSR si tu l’as. L’outil calcule l’empreinte de la clé publique de chaque objet et indique par des lettres ce qui va ensemble. Il fonctionne avec les clés RSA et ECC, les fichiers DER et les clés chiffrées. Rien n’est envoyé.

En ligne de commande, cela donne ceci. Les trois résultats doivent être identiques :

openssl x509 -in server.crt -noout -pubkey | openssl sha256
openssl pkey -in server.key -pubout       | openssl sha256
openssl req  -in server.csr -noout -pubkey | openssl sha256

La comparaison du modulus (-modulus), souvent conseillée, ne fonctionne qu’avec RSA. La comparaison de la clé publique fonctionne aussi avec ECDSA.

Si plusieurs clés traînent, voici comment trouver la bonne :

for k in /etc/ssl/private/*.key; do
  echo "$(openssl pkey -in "$k" -pubout 2>/dev/null | openssl sha256 | cut -d' ' -f2)  $k"
done

La solution

FAQ

Puis-je retrouver la clé privée à partir du certificat ?

Non. Le certificat ne contient que la clé publique. Si la clé privée est perdue, seule une nouvelle clé avec un nouveau CSR et une réémission permettent de s’en sortir.

Pourquoi la clé correspond-elle au CSR mais pas au certificat ?

Le certificat a alors été émis pour un autre CSR, p. ex. après plusieurs tentatives. Vérifie dans ton compte chez l’AC quel CSR a été utilisé, ou fais réémettre avec le bon CSR.

Est-il sûr de déposer la clé privée dans un outil web ?

Avec la correspondance de clé de hollop.net, rien n’est transmis : le calcul se fait en JavaScript dans ton navigateur. Pour une sécurité totale, utilise les commandes OpenSSL ci-dessus.