Des articles approfondis sur les technologies qui façonnent l'avenir.

Clés CA faibles d'eMudhra : 5 mythes PKI démolis

Une CA de confiance a livré des clés privées cassables en millisecondes. Cinq idées reçues sur la PKI, testées à partir de l'incident eMudhra.

Une immense porte de coffre-fort ouverte, protégée seulement par un minuscule cadenas en plastique
Dix-sept mois de sécurité d'autorité de certification ont reposé sur huit bits d'entropie.

L'une des clés privées d'autorité de certification d'eMudhra est le nombre 4. Pas un nombre de 384 bits qui commence par 4 : juste 4, avec 47 octets à zéro pour faire illusion. C'est une erreur de génération de clé d'autorité de certification que j'aurais cru impossible, et elle a survécu aux audits, à la certification croisée par Sectigo et à dix-sept mois d'infrastructure proche de la production, avant que quelqu'un ne tente le plus évident : brute-forcer un seul octet. Voici cinq idées reçues sur la PKI que cet incident enterre une bonne fois pour toutes.

Mythe 1 : « Un certificat structurellement valide est un certificat sûr »

Chaque contrôle automatisé du pipeline affirmait que ces certificats étaient corrects. Et ils avaient raison, dans un sens étroit et inutile. La clé publique correspondant à d = 4 est un point parfaitement valide sur la courbe P-384. L'encodage ASN.1 se parse. La signature se vérifie. La chaîne se construit. Chaque linter, chaque validateur structurel, chaque checklist de conformité qui parcourt un certificat et vérifie qu'il est bien formé le laissera passer, parce qu'il est bien formé.

C'est là le piège. La validation structurelle répond à la question « ce certificat est-il correctement formaté ? ». Elle ne répond pas à « la clé à l'intérieur a-t-elle été générée correctement ? ». Pour une clé de courbe elliptique, ce sont deux propriétés presque totalement indépendantes. La clé privée n'est qu'un scalaire d ; la clé publique est d × G, où G est le point générateur de la courbe. Toute la démonstration de sécurité repose sur le fait que retrouver d à partir du point public exige de résoudre le problème du logarithme discret — mais seulement si d a été réellement choisi dans l'espace complet de 384 bits. Si on choisit d dans 8 bits, le problème « impossible » devient une boucle de 255 itérations au maximum.

Rien dans le certificat résultant ne le laisse deviner. La clé publique dérivée de d = 4 paraît exactement aussi aléatoire que celle issue d'une clé correctement générée. Impossible de le voir à l'œil nu. Impossible de le détecter avec un linter. Le seul moyen de le savoir est de tester de petites valeurs et des motifs faibles connus, ce qui s'est justement passé : le rapporteur a lancé la suite de tests paranoid_crypto de Google sur le corpus de la Common CA Database, telle quelle, et a obtenu une alerte. Un contrôle qui prend quelques millisecondes sur un portable, appliqué à des clés qui ancrent la confiance de vrais navigateurs.

Première leçon : la validité est nécessaire, mais loin d'être suffisante. Si vos tests PKI s'arrêtent à « le certificat se parse et se chaîne », vous testez l'enveloppe et ignorez le contenu.

Mythe 2 : « Les exigences de référence et les audits détectent les bugs de génération de clés »

Les autorités de certification sont soumises aux Baseline Requirements du CA/Browser Forum et auditées selon les critères WebTrust ou ETSI. Il y a la documentation de cérémonie, les exigences HSM, les exigences de longueur de clé. Les clés d'eMudhra avaient la bonne longueur, 384 bits sur le papier. La faille de l'audit est que la conformité vérifie la représentation de la clé, pas l'entropie du processus qui l'a produite. Une clé remplie de 47 octets à zéro occupe toujours 48 octets sur le disque.

Selon le compte rendu d'eMudhra lui-même, publié sur le ticket d'incident de Mozilla, la cause racine se lit comme une comédie noire : un bug dans le script de cérémonie a généré une seconde paire de clés faible sur le HSM ; les deux paires avaient des noms similaires ; un humain a choisi la mauvaise pour la CSR. Trois défaillances distinctes, un bug de script, une collision de noms, une erreur de sélection, et à aucun moment un contrôle n'a demandé « cette clé a-t-elle réellement l'entropie pour laquelle on a payé le HSM ? »

C'est la partie qui devrait inquiéter tout ingénieur qui gère sa propre PKI interne. Si une autorité de certification publiquement reconnue, avec les programmes racines sur le dos et les audits au calendrier, peut livrer une clé privée égale à 4, que contiennent votre backend PKI Vault ou vos modèles Active Directory Certificate Services ? La correction coûte peu et il n'y a aucune excuse pour ne pas l'appliquer. Après avoir généré n'importe quelle clé, et avant de signer quoi que ce soit avec, passez-la dans paranoid_crypto ou, au minimum, dans une simple vérification de bon sens :

from cryptography.hazmat.primitives.asymmetric import ec
CURVE_ORDER_BITS = 384
def sanity_check_private_key(key: ec.EllipticCurvePrivateKey) -> None:
d = key.private_numbers().private_value
# Reject keys whose effective entropy is far below the curve size.
# A healthy P-384 key should have a bit length close to 384.
if d.bit_length() < CURVE_ORDER_BITS - 32:
raise ValueError(
f"Suspiciously small private scalar: {d.bit_length()} bits"
)
# Also reject known bad values outright.
if d < 2**16:
raise ValueError("Private scalar is trivially brute-forceable")

Trente secondes de travail. Cela aurait détecté chacune des huit clés d'eMudhra. Les audits vérifient que les processus existent ; ils ne vérifient pas qu'ils ont fonctionné un mardi d'avril donné. Seul le test des sorties le fait.

Mythe 3 : « Une clé d'autorité compromise peut être contenue »

Quand une clé d'autorité est « compromise » au sens habituel, il y a un voleur. Quelqu'un a exfiltré la clé à un moment précis, et vous pouvez raisonner sur le rayon d'impact : les certificats émis après le vol, par des parties disposant de la clé volée. Moche, mais borné. Nous avons déjà écrit sur ce qui se passe quand la compromission d'une autorité intermédiaire brise une chaîne de confiance, et le scénario standard (révoquer, retirer la confiance, réémettre) suppose un avant et un après.

Cet incident n'a ni avant ni après. La clé était effectivement publique dès la création du certificat, car quiconque a regardé ce certificat pouvait la retrouver en quelques millisecondes. Il n'y a pas d'événement de vol dont on puisse délimiter les effets. La fenêtre couvre toute la durée de vie des certificats, d'avril 2025 jusqu'à aujourd'hui, et il est impossible de savoir qui, le cas échéant, a franchi la porte ouverte. La déclaration d'eMudhra selon laquelle les intermédiaires n'ont émis aucun certificat d'entité finale, corroborée par les journaux de Certificate Transparency, est sincèrement rassurante pour ce que ces autorités ont fait. Elle ne dit rien de ce que quiconque détenant d=4 aurait pu faire de manière opportuniste sur un chemin réseau.

Pire encore, la réponse elle-même ne peut pas tout couvrir. Chrome et Firefox ont bloqué les intermédiaires en quelques heures via CRLSet et OneCRL, et comme ces navigateurs exigent la journalisation CT, les certificats TLS falsifiés n'auraient de toute façon jamais été validés. Très bien. Mais cette protection s'arrête à la frontière du navigateur, ce qui nous amène au mythe suivant.

Mythe 4 : « Si les navigateurs sont sûrs, l'écosystème l'est aussi »

Une fenêtre de navigateur blindée et lumineuse entourée de centaines d'appareils connectés exposés dans l'obscurité
Les navigateurs ont été corrigés en quelques heures ; tout le reste de l'écosystème TLS reste exposé.

Les navigateurs représentent le meilleur scénario de l'écosystème TLS, et ils constituent une minorité des clients TLS qui comptent pour vous sur le plan opérationnel. Pensez à ce qui établit réellement les connexions HTTPS dans votre infrastructure : curl, requests de Python, Node, les binaires Go, les services Java, git, les gestionnaires de paquets, les SDK cloud. Ces clients partagent trois caractéristiques qui se cumulent mal ici : ils font confiance à un bundle d'autorités stocké sur le disque, ils ne vérifient pas la révocation par défaut, et ils ne vérifient pas Certificate Transparency. Les trois protections qui ont sauvé les utilisateurs de Chrome sont absentes.

Scott Helme l'a démontré concrètement : avec un certificat falsifié pour api.stripe.com chaîné vers l'une des intermédiaires faibles d'eMudhra, le curl par défaut affichait SSL certificate verify ok, Python a terminé le handshake, Node a signalé la connexion comme autorisée, et Windows CryptoAPI a accepté la chaîne. Sur chaque machine Linux et macOS testée. Un certificat falsifié pour n'importe quel nom d'hôte, accepté par les outils par défaut sur lesquels vos scripts de déploiement et vos runners CI sont construits. Ce n'est pas un problème de navigateur, c'est un problème d'infrastructure, et c'est le vôtre.

La carte de l'exposition est pire que ce que la plupart imaginent :

  • Installateurs curl | sh et mises à jour automatiques. rustup, nvm, l'installateur Homebrew, d'innombrables pages « install.sh ». Un certificat falsifié ici revient à exécuter du code de l'attaquant, souvent en root.
  • Pipelines CI/CD. Les runners récupèrent des dépendances et publient des artefacts tout en détenant des identifiants cloud et des clés de signature, souvent sur des images de base obsolètes.
  • Trafic serveur à serveur. Webhooks de paiement, échanges de jetons OAuth, appels de SDK cloud transportant des secrets dans les en-têtes.
  • IoT et appareils embarqués. Firmwares figés avec des bundles d'autorités qui ne changeront pas avant l'expiration des certificats, en juillet 2039.
  • Signature de code Windows. Deux des huit clés faibles appartenaient à des autorités de signature de code ; un malware signé avec elles ressemble à un logiciel d'un éditeur légitime.

Le conseil actionnable est ennuyeux et juste : mettez à jour tout ce qui embarque un bundle d'autorités. Le paquet ca-certificates de votre OS, certifi, Node, Homebrew, et reconstruisez vos images de conteneurs une fois que les images de base auront intégré la défiance, car les couches gardent la mémoire. La partie non actionnable, c'est l'appareil que vous ne pouvez pas mettre à jour. Cette smart TV fera confiance à une clé égale à 4 pendant encore une décennie et demie. Si vous aviez besoin d'un argument de plus pour segmenter le réseau de vos objets connectés, le voilà.

Mythe 5 : « Quelqu'un doit forcément déjà vérifier ça »

La ligne la plus discrètement accablante de l'incident vient du rapporteur : la découverte est venue de l'exécution de paranoid_crypto sur le corpus CCADB, comme simple test rapide du corpus avant de passer aux certificats d'abonnés. Le fruit le plus facile à cueillir. Selon les propres mots du rapporteur : « La plupart de mon temps a été consacré à revoir les bases que tout le monde supposait que quelqu'un d'autre avait déjà faites, une erreur critique à ne jamais commettre en matière de sécurité. »

Relisez-le. Huit clés privées d'autorité de certification, les bijoux de famille d'une autorité publiquement reconnue, certifiées croisées vers la racine AAA Certificate Services de Sectigo, sont restées attaquables par force brute pendant dix-sept mois. Elles n'ont été trouvées ni par un auditeur, ni par un programme racine, ni par l'autorité elle-même, mais par une seule personne exécutant un outil open source tel quel. L'écosystème a collectivement supposé que les bases étaient couvertes. Personne ne les avait couvertes.

C'est un schéma plus large dans l'infrastructure de sécurité, et c'est pour cela que je reviens sans cesse sur la conception défensive, des systèmes qui résistent aux catastrophes, plutôt que des systèmes qui supposent un fonctionnement correct. Les contrôles qui auraient détecté ceci sont d'un coût presque honteusement faible :

  1. Exécutez paranoid_crypto ou un équivalent de détection de clés faibles sur chaque clé au moment de sa génération et sur chaque CSR avant signature.
  2. Vérifiez l'entropie empiriquement : contrôlez la longueur en bits du scalaire privé et rejetez toute clé dont l'entropie effective est implausiblement faible, comme dans l'exemple de code ci-dessus.
  3. Testez la cérémonie, pas seulement la configuration. Répétez vos cérémonies de clés à blanc et inspectez les artefacts réellement produits, y compris l'objet HSM nommé qui finit dans la CSR.
  4. Analysez en continu vos certificats émis, pas seulement vos modèles. Le certificat est la vérité terrain ; tout ce qui est en amont relève de l'intention.

Le certificat est la vérité terrain. Tout ce qui est en amont (scripts, cérémonies, audits) n'est qu'intention.

Huit bits suffisent

Il y a quelque chose de presque rassurant dans une catastrophe à la cause dérisoire. Un bug de script, deux clés aux noms similaires sur un HSM, un humain qui choisit la mauvaise : pas d'État-nation, pas de cryptanalyse inédite, juste un épisode des Trois Stooges avec une mèche de dix-sept mois. Mais cette absurdité est un avertissement. Si le maillon le plus faible d'une autorité de certification publiquement reconnue peut tenir dans un seul octet, alors la solidité de votre PKI ne dépend ni de votre choix de courbe ni de votre budget HSM. Elle dépend de la question de savoir si quelqu'un, quelque part dans le pipeline, a réellement testé la sortie.

Les éditeurs de navigateurs ont fait leur part en quelques heures. Le reste nous incombe : auditez votre propre génération de clés, lancez les contrôles peu coûteux, mettez à jour chaque bundle d'autorités que vous pouvez atteindre, et segmentez les appareils que vous ne pouvez pas mettre à jour. Et arrêtez de supposer que quelqu'un d'autre a déjà vérifié les bases. En matière de sécurité, c'est l'hypothèse la plus coûteuse qui soit.