Aller au contenu
ecdsa.com
← Tous les articles

ssh-keygen en 2026 : types de clés, phrase de passe, agent

D’OpenSSH 10.0 à 10.6, bien plus de valeurs par défaut ont changé que la plupart des gens ne l’ont remarqué : échange de clés post-quantique, type de signature hybride ML-DSA, davantage de tours de KDF, sockets d’agent dans votre répertoire personnel. Chaque commande ci-dessous a été exécutée sous OpenSSH 10.6p1, et la sortie affichée est la sortie réelle.

En bref. Exécutez ssh-keygen -t ed25519 -C "you@host-year" et protégez la clé par une phrase de passe ; Ed25519 est le type par défaut depuis OpenSSH 9.5. Si vous avez une clé de sécurité FIDO2, préférez -t ed25519-sk (ou -t ecdsa-sk si l’authentificateur ne prend pas en charge Ed25519), pour que la clé privée ne se trouve jamais sur le disque. Réservez RSA aux systèmes qui ne savent rien faire d’autre, et dans ce cas avec 3072 bits ou plus : depuis le 14 octobre 2026, GitHub refuse les nouvelles clés RSA plus petites. Chargez les clés dans l’agent avec une durée de vie (ssh-add -t 8h), ne transférez pas l’agent vers des hôtes que vous ne contrôlez pas (utilisez ProxyJump) et restreignez les clés à des destinations avec ssh-add -h. Pour un parc de serveurs, remplacez les entrées authorized_keys dispersées par des certificats SSH à courte durée de vie. La protection post-quantique de la session est déjà active : OpenSSH 10 négocie mlkem768x25519-sha256 par défaut et affiche un avertissement quand un serveur n’en est pas capable. Le nouveau type de signature hybride ssh-mldsa44-ed25519 (OpenSSH 10.6) mérite d’être testé, mais pas encore d’être déployé comme seule clé.

Les commandes ont été exécutées le 20 octobre 2026 dans debian:forky-20261005-slim, avec les paquets Debian openssh-client et openssh-server 1:10.6p1-1. Toutes les clés ont été générées pour cet article.

Quel type de clé

-tCe que c’estQuand l’utiliser
ed25519 (par défaut)Ed25519, clé publique de 32 octets, signatures déterministesPresque toujours
ed25519-sk, ecdsa-skClé FIDO2 : le secret reste dans l’authentificateur, chaque signature exige un toucherVous avez une clé de sécurité et le serveur utilise OpenSSH 8.2 ou une version ultérieure
ecdsaECDSA sur P-256, P-384 ou P-521Une politique impose les courbes NIST
rsaRSA, 3072 bits par défaut depuis OpenSSH 8.0Anciens serveurs, équipements dédiés, certains HSM
mldsa44-ed25519Signature hybride ML-DSA-44 + Ed25519, nouveauté de la 10.6Tester l’authentification post-quantique

DSA a disparu : OpenSSH 10.0 (avril 2025) l’a supprimé, « achevant le processus de dépréciation entamé en 2015 ». Les clés RSA restent utilisables ; ce qu’OpenSSH 8.8 (septembre 2021) a désactivé, c’est l’algorithme de signature ssh-rsa, qui hache avec SHA-1. La même clé RSA signe avec rsa-sha2-256 ou rsa-sha2-512, c’est pourquoi l’erreur du serveur à propos de ssh-rsa se corrige généralement en mettant à jour le client, et non en remplaçant la clé. GitHub suit la même logique : il supprimera les signatures ssh-rsa le 13 janvier 2027, après des coupures temporaires (brownouts) les 4 novembre et 9 décembre 2026, et depuis le 14 octobre 2026, il n’accepte de nouvelles clés RSA qu’à partir de 3072 bits.

Les tailles, telles que ssh-keygen 10.6 les écrit (la ligne .pub inclut le commentaire) :

Clés RSA et ECDSA par défaut, la clé hybride et la clé Ed25519 de la section suivante
ssh-keygen -q -t rsa -N '' -f ~/rsa_default
ssh-keygen -q -t ecdsa -N '' -f ~/ecdsa_default
ssh-keygen -q -t mldsa44-ed25519 -N '' -f ~/.ssh/id_mldsa44_ed25519
for f in ~/rsa_default ~/ecdsa_default ~/.ssh/id_ed25519 ~/.ssh/id_mldsa44_ed25519; do
  ssh-keygen -l -f "$f.pub"
  printf '  public key line: %s bytes, private key file: %s bytes\n' "$(wc -c < "$f.pub")" "$(wc -c < "$f")"
done
Sortie (OpenSSH 10.6p1)
3072 SHA256:NGv36ZHCwauN4GGrdKSDZPnKTn6nFuLSVRS01/eSXOs alice@59151e7fff6c (RSA)
  public key line: 572 bytes, private key file: 2602 bytes
256 SHA256:4ODqYFVTGSwjx7pfis5ZtZ02PKaSd15alII7RIHPhE8 alice@59151e7fff6c (ECDSA)
  public key line: 180 bytes, private key file: 513 bytes
256 SHA256:I72RDcR38Z+glA2IhaHUj/h844afNwkK9siDEGHv24c alice@laptop-2026 (ED25519)
  public key line: 99 bytes, private key file: 464 bytes
512 SHA256:oqHqur1575V136Khl2P7Gaa6rM+2dPT51B6YfjLSxB4 alice@59151e7fff6c (MLDSA44-ED25519)
  public key line: 1868 bytes, private key file: 3982 bytes

La ligne de clé publique hybride est 19 fois plus longue que celle d’une clé Ed25519. Cela compte pour les fichiers authorized_keys, les certificats et tout ce qui stocke des clés dans une colonne de base de données dimensionnée pour Ed25519. La comparaison Ed25519 vs RSA traite en détail la paire classique.

Générer une clé

Générer une clé Ed25519 avec un commentaire qui indique où elle se trouve
ssh-keygen -t ed25519 -C "alice@laptop-2026" -N 'correct horse battery staple' -f ~/.ssh/id_ed25519
Sortie (OpenSSH 10.6p1)
Created directory '/home/alice/.ssh'.
Generating public/private ed25519 key pair.
Your identification has been saved in /home/alice/.ssh/id_ed25519
Your public key has been saved in /home/alice/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:I72RDcR38Z+glA2IhaHUj/h844afNwkK9siDEGHv24c alice@laptop-2026
The key's randomart image is:
+--[ED25519 256]--+
|     ..o*.....   |
| o  . .=... =.   |
|. o  .. +. + o.  |
| . . . o =. . ...|
|  o   + S ..   ..|
| . . o + B       |
|  . * = * o .    |
|   o E = o.+     |
|      o oo. .    |
+----[SHA256]-----+

-N transmet la phrase de passe sur la ligne de commande uniquement parce que l’environnement de test est scripté ; en usage interactif, omettez cette option : ssh-keygen demande alors la phrase de passe, qui ne se retrouve donc pas dans l’historique du shell. Le commentaire est un texte libre stocké dans la clé publique : un nom, une machine et une année permettent d’auditer un fichier authorized_keys des années plus tard. L’empreinte (SHA256:…) est ce que les serveurs journalisent : notez-la chaque fois que vous enregistrez la clé quelque part.

Phrase de passe et tours de KDF

Sans phrase de passe, le fichier de clé privée est la clé : une sauvegarde volée, une image disque d’ordinateur portable ou un dossier de synchronisation mal configuré suffit à la livrer. Avec une phrase de passe, le fichier est chiffré avec une clé dérivée par bcrypt_pbkdf. Le format de clé privée OpenSSH consigne l’algorithme de chiffrement, la KDF et son nombre de tours dans un en-tête que n’importe qui peut lire sans la phrase de passe :

kdfinfo.py : lire l’algorithme de chiffrement, la KDF et le nombre de tours d’une clé privée OpenSSH
"""Print the cipher, KDF and bcrypt rounds from the header of an OpenSSH private key file (openssh-key-v1)."""
import base64
import struct
import sys

text = open(sys.argv[1]).read()
body = "".join(line for line in text.splitlines() if not line.startswith("-----"))
blob = base64.b64decode(body)
magic = b"openssh-key-v1\0"
assert blob.startswith(magic), "not an OpenSSH private key"
pos = len(magic)


def string():
    global pos
    (length,) = struct.unpack(">I", blob[pos : pos + 4])
    value = blob[pos + 4 : pos + 4 + length]
    pos += 4 + length
    return value


cipher = string().decode()
kdf = string().decode()
options = string()
line = f"cipher={cipher} kdf={kdf}"
if kdf == "bcrypt":
    (salt_len,) = struct.unpack(">I", options[:4])
    (rounds,) = struct.unpack(">I", options[4 + salt_len : 8 + salt_len])
    line += f" salt={salt_len} bytes rounds={rounds}"
print(line)
Nombre de tours par défaut, puis coût du déverrouillage à 32, 100 et 500 tours
python3 kdfinfo.py ~/.ssh/id_ed25519
for r in 32 100 500; do
  ssh-keygen -q -p -a $r -P 'correct horse battery staple' -N 'correct horse battery staple' -f ~/.ssh/id_ed25519 >/dev/null
  s=$(date +%s.%N); ssh-keygen -y -P 'correct horse battery staple' -f ~/.ssh/id_ed25519 >/dev/null; e=$(date +%s.%N)
  printf 'rounds=%s unlock=%.2fs\n' $r $(echo "$e - $s" | bc)
done
Sortie (un cœur arm64 dans Docker sur un Apple M4 Max)
cipher=aes256-ctr kdf=bcrypt salt=16 bytes rounds=32
rounds=32 unlock=0.16s
rounds=100 unlock=0.52s
rounds=500 unlock=2.59s

La valeur par défaut était de 16 tours jusqu’à OpenSSH 9.4, de 24 à partir de la 9.4, et elle est de 32 depuis la 10.6. Le coût est linéaire en fonction du nombre de tours, comme le soulignent les notes de version de la 10.6 (« contrairement à bcrypt(3), qui est exponentiel »), si bien que les chiffres ci-dessus évoluent de façon prévisible : choisissez la plus grande valeur dont vous acceptez le délai de déverrouillage, car un attaquant qui a copié le fichier paie le même prix pour chaque tentative. ssh-keygen -p -a 100 -f ~/.ssh/id_ed25519 rechiffre une clé existante ; si vous la chargez dans l’agent une fois par session, vous ne payez ce délai qu’une fois. Depuis la 10.6, OpenSSH refuse les clés de plus d’un million de tours, si bien qu’un fichier de clé malveillant ne peut pas bloquer un service qui l’analyse.

Une phrase de passe protège le fichier au repos. Elle n’apporte plus rien une fois la clé déchiffrée dans un agent sur une machine compromise : c’est là qu’interviennent les clés matérielles.

Clés matérielles : -sk

Les clés ed25519-sk et ecdsa-sk (OpenSSH 8.2 et versions ultérieures) conservent le secret dans un authentificateur FIDO2, comme une YubiKey ou un authentificateur de plateforme. Le fichier ~/.ssh/id_ed25519_sk ne contient alors qu’une référence de clé (key handle), dont l’authentificateur a besoin pour reconstituer la clé ; sans l’appareil, ce fichier est inutile. Chaque signature exige la présence de l’utilisateur (un toucher) et, avec -O verify-required, également un PIN. Les options importantes, citées d’après ssh-keygen(1) :

  • -O resident stocke la référence de clé sur l’authentificateur, si bien que ssh-keygen -K ou ssh-add -K peuvent la charger sur un autre ordinateur. Le manuel avertit que cela « augmente la probabilité qu’un attaquant puisse utiliser un authentificateur volé » : combinez donc cette option avec un PIN.
  • -O verify-required exige la vérification de l’utilisateur (actuellement un PIN) pour chaque signature ; le serveur peut l’imposer avec l’option verify-required dans authorized_keys.
  • -O application=ssh:work distingue plusieurs clés résidentes sur un même appareil ; la chaîne doit commencer par ssh:.
  • -O no-touch-required supprime le toucher, et sshd refuse de telles signatures sauf si authorized_keys les autorise explicitement.
  • -O write-attestation=path enregistre l’attestation de l’authentificateur, qui permet à une organisation de prouver, lors de l’enrôlement, que la clé a été créée sur un matériel approuvé.
Enrôlement type d’une clé résidente protégée par PIN (nécessite un authentificateur FIDO2)
ssh-keygen -t ed25519-sk -O resident -O verify-required -O application=ssh:work -C "alice@yubikey-2026"

Nous n’avons pas exécuté cette commande : le conteneur n’a pas d’authentificateur, et une transcription sans authentificateur n’afficherait que l’erreur. Certains authentificateurs anciens n’implémentent que P-256 ; utilisez ecdsa-sk pour ceux-là. Les clés de plateforme fonctionnent aussi, mais les clés conservées par le matériel sécurisé d’un ordinateur portable ont leurs propres compromis, présentés dans les clés matérielles.

Post-quantique : l’échange de clés maintenant, les signatures plus tard

Les deux moitiés de SSH n’ont pas la même échéance. Les clés de session proviennent de l’échange de clés ; s’il est cassé plus tard, le trafic enregistré peut être déchiffré (récolter maintenant, déchiffrer plus tard). Les signatures d’hôte et d’utilisateur ne comptent qu’au moment de la connexion : un futur ordinateur quantique ne pourra pas remonter le temps pour falsifier une connexion qui a déjà eu lieu. OpenSSH a donc commencé par changer l’échange de clés :

  • sntrup761x25519-sha512 est activé par défaut depuis OpenSSH 9.0 (2022) ;
  • mlkem768x25519-sha256, soit ML-KEM-768 combiné à X25519, est l’algorithme par défaut depuis OpenSSH 10.0 (avril 2025) et il est désormais spécifié dans la RFC 10042 (informative, 2026) ;
  • depuis la 10.1, le client affiche un avertissement quand la session se replie sur un échange classique, et depuis la 10.6, le serveur le journalise.
ssh -v localhost true, paramètres par défaut des deux côtés (sortie filtrée avec grep)
debug1: kex: algorithm: mlkem768x25519-sha256
debug1: kex: host key algorithm: ssh-ed25519
debug1: Server host key: ssh-ed25519 SHA256:Qw4tNHnCo8UwS2qNXROrEm8RP+d+ccaVbwAzv8lLX+I
debug1: Offering public key: /home/alice/.ssh/id_ed25519 ED25519 SHA256:I72RDcR38Z+glA2IhaHUj/h844afNwkK9siDEGHv24c agent
debug1: Server accepts key: /home/alice/.ssh/id_ed25519 ED25519 SHA256:I72RDcR38Z+glA2IhaHUj/h844afNwkK9siDEGHv24c agent
Authenticated to localhost ([::1]:22) using "publickey".

Face à un serveur limité à KexAlgorithms curve25519-sha256,ecdh-sha2-nistp256, le client, dans sa configuration par défaut, a affiché :

Sortie du client quand le serveur ne propose aucun échange de clés post-quantique
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html

Deux détails que nous avons observés : le client reste silencieux quand c’est vous qui limitez KexAlgorithms à une méthode classique (l’avertissement vise les serveurs), et le serveur journalise chaque session de ce type, par exemple connection from ::1 port 38814 is not using a post-quantum key exchange algorithm: "curve25519-sha256" [preauth]. WarnWeakCrypto no-pq-kex dans un bloc Match host fait taire le client pour un hôte que vous ne pouvez pas corriger, comme le suggère openssh.com/pq.html. GitHub a annoncé mlkem768x25519-sha256 pour github.com à partir du 14 octobre 2026 ; le 20 octobre, notre client 10.6 l’a négocié avec git@github.com.

Les signatures constituent la deuxième étape. OpenSSH 10.4 a ajouté un schéma composite expérimental associant ML-DSA-44 et Ed25519 ; la 10.6 l’a activé sous le nom ssh-mldsa44-ed25519, spécifié dans l’Internet-Draft du groupe de travail SSHM draft-ietf-sshm-composite-sigs. Les clés créées avec le code expérimental de la 10.4 doivent être régénérées. Dans le paquet Debian 10.6, ssh-keygen -A a créé ssh_host_mldsa44_ed25519_key à côté des clés d’hôte RSA, ECDSA et Ed25519, et ce type figure en dernière position dans la valeur par défaut de HostKeyAlgorithms, si bien que les clients choisissent toujours Ed25519. Le demander explicitement fonctionne de bout en bout :

ssh -v -o HostKeyAlgorithms=ssh-mldsa44-ed25519 -o IdentitiesOnly=yes -i ~/.ssh/id_mldsa44_ed25519 (sortie filtrée)
debug1: kex: host key algorithm: ssh-mldsa44-ed25519
debug1: Server host key: ssh-mldsa44-ed25519 SHA256:UVOUu+csMH8i8Zd/oWzokAGfzRYFetOncVzB4vYeMgQ
debug1: Server accepts key: /home/alice/.ssh/id_mldsa44_ed25519 MLDSA44-ED25519 SHA256:oqHqur1575V136Khl2P7Gaa6rM+2dPT51B6YfjLSxB4 explicit
Authenticated to localhost ([::1]:22) using "publickey".

Les deux moitiés signent le même message, avec séparation de domaine, et « l’échec de l’une ou l’autre des opérations de vérification DOIT entraîner l’échec de la vérification de la signature composite » : l’hybride n’est donc pas plus faible qu’Ed25519 aujourd’hui. Son coût tient à la taille (une signature de 2484 octets par authentification, selon l’Internet-Draft) et à la compatibilité : les serveurs, forges logicielles, bastions et bibliothèques qui ne connaissent pas ce type n’accepteront pas la clé. Générez-en une, testez-la sur les hôtes que vous administrez et gardez votre clé Ed25519 enregistrée en parallèle.

L’agent et le transfert d’agent

ssh-agent conserve les clés déchiffrées et signe à la demande ; les programmes le joignent par le socket indiqué dans SSH_AUTH_SOCK. Depuis OpenSSH 10.1, ce socket se trouve sous ~/.ssh/agent plutôt que dans /tmp. Ajoutez les clés avec une durée de vie, afin qu’une session oubliée ne les garde pas déverrouillées indéfiniment :

Démarrer un agent et ajouter la clé pour huit heures (l’environnement de test fournit la phrase de passe via SSH_ASKPASS)
eval "$(ssh-agent -s)" >/dev/null
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK"
ssh-add -t 8h ~/.ssh/id_ed25519
ssh-add -l
Sortie
SSH_AUTH_SOCK=/home/alice/.ssh/agent/s.eaeHp0xOjD.local.660.o5M944i4eW
Identity added: /home/alice/.ssh/id_ed25519 (alice@laptop-2026)
Lifetime set to 08:00:00
256 SHA256:I72RDcR38Z+glA2IhaHUj/h844afNwkK9siDEGHv24c alice@laptop-2026 (ED25519)

AddKeysToAgent dans ~/.ssh/config fait de même à la première utilisation et accepte une durée de vie (AddKeysToAgent 8h) ou confirm, qui demande une confirmation avant chaque signature, comme ssh-add -c.

Le transfert d’agent (ssh -A, ForwardAgent yes) expose ce socket sur l’hôte distant. ssh_config(5) énonce clairement le risque : « Un attaquant ne peut pas obtenir le matériel de clé à partir de l’agent, mais il peut effectuer des opérations avec les clés ». Toute personne disposant des droits root sur l’hôte distant peut se connecter en votre nom partout où vos clés fonctionnent, aussi longtemps que vous restez connecté. Deux habitudes préférables :

  • Rebondissez au lieu de transférer. ssh -J bastion target (ou ProxyJump bastion dans la configuration) établit la seconde connexion depuis votre machine, à travers un flux TCP transféré ; le bastion ne voit jamais votre agent.
  • Restreignez les clés. ssh-add -h (OpenSSH 8.9 et versions ultérieures) lie une clé à des destinations identifiées par leurs clés d’hôte issues de known_hosts, et à des sauts (bastion>target) lorsque vous transférez malgré tout l’agent.
dest.sh (extrait) : une clé qui ne fonctionne que pour prod-host
ssh-add -h prod-host ~/agent_only_key
ssh -o BatchMode=yes prod-host 'echo signed in on prod-host'
ssh -v -o BatchMode=yes build-host true 2>&1 | grep -iE 'agent|Offering|Permission denied|Authenticated|identity'
Sortie (abrégée : les lignes où le client essaie les fichiers d’identité sont omises)
Identity added: /home/alice/agent_only_key (alice@laptop)
signed in on prod-host
debug1: get_agent_identities: bound agent to hostkey
debug1: get_agent_identities: ssh_fetch_identitylist: agent contains no identities
debug1: Offering public key: /home/alice/.ssh/id_ed25519 ED25519 SHA256:MA2nEhBnMlCkX3pWWgPtff90dRZF9D9k8i2svCUK1II
alice@127.0.0.2: Permission denied (publickey,password).

L’agent a lié la session à la clé d’hôte de build-host, puis n’a listé aucune identité pour elle : la clé existe, mais pas pour cette destination. Le manuel précise soigneusement la limite : une contrainte « n’empêche pas un attaquant ayant accès à un SSH_AUTH_SOCK distant de le transférer à nouveau et de l’utiliser sur un autre hôte (mais uniquement vers une destination autorisée) ».

Des certificats au lieu d’authorized_keys

Copier des clés publiques dans authorized_keys sur chaque serveur ne passe pas à l’échelle et transforme la révocation en problème de recherche. Un certificat SSH est une clé publique signée par une clé d’AC, accompagnée d’une identité, de principaux, d’un numéro de série et d’une période de validité. Les serveurs font confiance à l’AC une seule fois (TrustedUserCAKeys) et consultent une liste de révocation (RevokedKeys) :

Signer une clé utilisateur pour 8 heures, se connecter, la révoquer par numéro de série, réessayer (exécuté en root sur le serveur de test)
ssh-keygen -s /etc/ssh/user_ca -I "alice@example.com 2026-10-20" -n alice -V +8h -z 1042 /home/alice/.ssh/id_cert_user.pub
ssh-keygen -L -f /home/alice/.ssh/id_cert_user-cert.pub
su - alice -c 'ssh -o IdentitiesOnly=yes -o IdentityAgent=none -i ~/.ssh/id_cert_user localhost "echo logged in with certificate"'
echo "serial: 1042" > /tmp/revoke.txt
ssh-keygen -k -u -s /etc/ssh/user_ca.pub -f /etc/ssh/revoked.krl /tmp/revoke.txt
ssh-keygen -Q -f /etc/ssh/revoked.krl /home/alice/.ssh/id_cert_user-cert.pub
su - alice -c 'ssh -o IdentitiesOnly=yes -o IdentityAgent=none -o BatchMode=yes -i ~/.ssh/id_cert_user localhost true'
Sortie (sshd tourne avec TrustedUserCAKeys /etc/ssh/user_ca.pub et RevokedKeys /etc/ssh/revoked.krl)
Signed user key /home/alice/.ssh/id_cert_user-cert.pub: id "alice@example.com 2026-10-20" serial 1042 for alice valid from 2026-10-20T14:33:00 to 2026-10-20T22:34:33
/home/alice/.ssh/id_cert_user-cert.pub:
        Type: ssh-ed25519-cert-v01@openssh.com user certificate
        Public key: ED25519-CERT SHA256:eVstR5lK6VBztjl2AYyWcv8C6xwNahEEVSrQpe7Y/LE
        Signing CA: ED25519 SHA256:+URM6AMiGUu+gv/gxoQgpOhHP4CUN1fznXWDlVxorbY (using ssh-ed25519)
        Key ID: "alice@example.com 2026-10-20"
        Serial: 1042
        Valid: from 2026-10-20T14:33:00 to 2026-10-20T22:34:33
        Principals: 
                alice
        Critical Options: (none)
        Extensions: 
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc
logged in with certificate
Revoking from /tmp/revoke.txt
/home/alice/.ssh/id_cert_user-cert.pub (alice@ci-runner): REVOKED
alice@localhost: Permission denied (publickey).

sshd a journalisé key ED25519-CERT SHA256:eVst… revoked by file /etc/ssh/revoked.krl. Notez les extensions par défaut : un certificat autorise le transfert d’agent et de ports, sauf si vous signez avec -O clear et ne rajoutez que le nécessaire (-O permit-pty). Conservez la clé d’AC hors ligne ou dans un HSM, émettez des certificats valables quelques heures plutôt que plusieurs années, et les courtes durées de vie rendront la plupart des révocations inutiles. Les certificats d’hôte (-h lors de la signature, @cert-authority dans known_hosts) suppriment de la même façon l’invite de confiance à la première utilisation.

Rotation des clés

  • Clés utilisateur. Générez la nouvelle clé, ajoutez sa clé publique à côté de l’ancienne partout (serveurs, forges, secrets de CI), connectez-vous avec -i new_key -o IdentitiesOnly=yes pour vérifier qu’elle fonctionne, puis supprimez l’ancienne ligne. Un commentaire daté vous indique quelle ligne est l’ancienne.
  • Clés d’hôte. UpdateHostKeys est activé par défaut depuis OpenSSH 8.5 (sauf si vous redéfinissez UserKnownHostsFile ou activez VerifyHostKeyDNS) : après l’authentification, le serveur annonce toutes ses clés d’hôte et le client enregistre les nouvelles, si bien qu’un serveur peut publier une clé de remplacement avant de retirer l’ancienne. Les clients qui se connectent rarement manquent cette fenêtre ; les certificats d’hôte évitent le problème.
  • Algorithmes. Le même mécanisme permet une migration : ajoutez une clé d’hôte Ed25519 (et, plus tard, une clé hybride), laissez les clients l’apprendre, puis supprimez la clé RSA.
  • Inventaire. ssh-keygen -l -f authorized_keys affiche une empreinte par ligne ; comparez-les avec les lignes Accepted publickey … SHA256: du journal de sshd pour trouver les clés que personne n’utilise.

Erreurs fréquentes

  • Un fichier de clé lisible par tous. ssh refuse de l’utiliser et affiche WARNING: UNPROTECTED PRIVATE KEY FILE!. Appliquez chmod 600 à la clé et 700 au répertoire .ssh.
  • Une mauvaise phrase de passe ou une clé convertie. incorrect passphrase supplied to decrypt private key et error in libcrypto se ressemblent ; la seconde erreur signifie généralement que le fichier est endommagé ou dans un format que le build ne sait pas lire. Les bibliothèques ont besoin que la phrase de passe leur soit fournie explicitement, comme le montre l’erreur Go this private key is passphrase protected.
  • Trop de clés dans l’agent. sshd abandonne après MaxAuthTries (6) tentatives échouées et coupe la connexion avec Too many authentication failures, et chaque clé que le client essaie peut consommer une tentative (les serveurs OpenSSH 10.6 autorisent six requêtes supplémentaires du type « accepteriez-vous cette clé ? », PubkeyOptions max-pk-ok). Définissez IdentityFile et IdentitiesOnly yes pour chaque hôte. Si aucune clé proposée n’est enregistrée, vous obtenez Permission denied (publickey).
  • L’agent refuse. agent refused operation signifie que le serveur a accepté la clé, mais que l’agent n’a pas voulu signer : une clé FIDO qui n’a pas été touchée à temps, une confirmation qu’il ne peut pas afficher, un jeton verrouillé, ou un fichier de clé sur le disque qui ne correspond plus à ce que détient l’agent.
  • Pairs trop anciens. no matching host key type found. Their offer: ssh-rsa signifie que le serveur ne sait signer qu’avec SHA-1. Mettez-le à jour ; un HostKeyAlgorithms +ssh-rsa par hôte est une exception temporaire, jamais un paramètre global.
  • Ignorer un changement de clé d’hôte. REMOTE HOST IDENTIFICATION HAS CHANGED signale soit une rotation planifiée que vous pouvez confirmer par un autre canal, soit exactement l’attaque que cette vérification doit détecter. Ne supprimez l’ancienne ligne avec ssh-keygen -R host qu’une fois que vous savez de quel cas il s’agit.

Liste de contrôle

  1. ssh-keygen -t ed25519 (ou -t ed25519-sk avec une clé de sécurité), une phrase de passe, un commentaire indiquant le propriétaire, la machine et l’année.
  2. Augmentez le nombre de tours de KDF jusqu’au délai que vous acceptez (-a 100 coûte ici environ une demi-seconde).
  3. Une clé par appareil ; ne copiez jamais de clés privées d’une machine à l’autre.
  4. Agent avec durées de vie ; IdentitiesOnly yes par hôte ; ProxyJump au lieu de ForwardAgent ; ssh-add -h quand le transfert est inévitable.
  5. Parcs de serveurs : certificats utilisateur et d’hôte à courte validité, clé d’AC hors ligne, une KRL sur chaque serveur.
  6. Cherchez kex: algorithm: mlkem768x25519-sha256 dans la sortie de ssh -v ; traitez l’avertissement post-quantique comme un ticket de mise à jour du serveur.
  7. Testez les clés mldsa44-ed25519 sur vos propres serveurs ; gardez une clé classique enregistrée jusqu’à ce que chaque pair accepte l’hybride.

Sources