Aller au contenu
ecdsa.com

X25519MLKEM768 vs X25519 : échange post-quantique en TLS

Le groupe hybride ajoute environ 1,2 Ko au ClientHello et protège le trafic enregistré contre les futurs ordinateurs quantiques. C’est déjà le choix par défaut des navigateurs, d’OpenSSL et de Go.
Éléments comparésX25519MLKEM768X25519

X25519MLKEM768 vs X25519, c’est le choix d’échange de clés que pose aujourd’hui chaque handshake TLS 1.3. X25519 seul est rapide et très compact, mais il ne résiste pas à un ordinateur quantique : le trafic enregistré aujourd’hui pourrait donc être déchiffré plus tard. X25519MLKEM768 exécute X25519 et ML-KEM-768 ensemble, si bien que la session reste confidentielle à moins que les deux ne soient cassés.

Vue d’ensemble

X25519X25519MLKEM768
Groupe pris en charge (TLS)x25519, 29 (0x001D)X25519MLKEM768, 4588 (0x11EC), recommandé par l’IANA
SpécificationRFC 7748, RFC 9846RFC 10024 (2026), cadre général RFC 9954
ComposantsX25519ML-KEM-768 (FIPS 203) et X25519
Key share du client32 octets1216 octets (clé d’encapsulation ML-KEM de 1184 octets + 32)
Key share du serveur32 octets1120 octets (chiffré ML-KEM de 1088 octets + 32)
Secret partagé fourni à la dérivation des clés (key schedule)32 octets64 octets (secret ML-KEM d’abord, puis X25519)
Résistance au quantiqueNonOui, tant que ML-KEM-768 tient
Sécurité classiqueX25519Au moins celle de X25519, même si ML-KEM était cassé
CPU par handshake, OpenSSL 3.6.5environ 52 000 opérations X25519 par secondeenviron 19 000–24 000 générations de clés, encapsulations ou décapsulations par seconde
ClientHello mesuré ci-dessous306 octets1484 octets
ServerHello mesuré ci-dessous122 octets1210 octets

Débit mesuré avec openssl speed sur un cœur d’Apple M4 Max ; tailles de handshake issues de la capture ci-dessous.

Pourquoi l’hybride dès maintenant

L’échange de clés est exposé au scénario récolter maintenant, déchiffrer plus tard : un adversaire enregistre aujourd’hui des sessions chiffrées et les déchiffre dès qu’existe un ordinateur quantique cryptographiquement pertinent, en retrouvant les clés de session à partir de l’échange X25519 enregistré. La confidentialité persistante n’y change rien, car chaque échange enregistré peut être cassé séparément. Tout ce dont la confidentialité doit survivre à l’arrivée d’un tel ordinateur est déjà menacé : c’est pourquoi l’échange de clés a migré en premier, tandis que les signatures peuvent attendre plus longtemps.

La conception hybride couvre aussi le risque inverse. ML-KEM a été normalisé en août 2024 et reste jeune comparé à X25519 : un cassage mathématique ou une faille d’implémentation n’est donc pas impensable. X25519MLKEM768 concatène les deux secrets partagés dans la dérivation des clés TLS, si bien qu’un attaquant doit casser les deux. Pour ce groupe, la RFC 10024 place en premier la key share et le secret ML-KEM, contrairement aux hybrides sur courbes NIST (SecP256r1MLKEM768, 0x11EB, et SecP384r1MLKEM1024, 0x11ED), qui placent ECDH en premier.

Ce qui change sur le réseau

Le client envoie une key share de 1216 octets au lieu de 32 octets : un ClientHello typique passe ainsi d’environ 300 octets à environ 1,5 Ko et, avec toutes les autres extensions d’un navigateur, ne tient plus dans un seul paquet réseau. Le serveur répond avec une key share de 1120 octets. Un handshake réel avec Cloudflare, capturé avec OpenSSL 3.6.5, montre la différence :

OpenSSL 3.6.5 : handshake TLS 1.3 avec chaque groupe
echo | openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519MLKEM768 -brief 2>&1 | grep -E "Protocol|group"
echo | openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519MLKEM768 -msg 2>&1 | grep -E "ClientHello|ServerHello"
echo | openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519 -msg 2>&1 | grep -E "ClientHello|ServerHello"
Sortie du 20 octobre 2026 (longueurs en hexadécimal)
Protocol version: TLSv1.3
Negotiated TLS1.3 group: X25519MLKEM768
>>> TLS 1.3, Handshake [length 05cc], ClientHello
<<< TLS 1.3, Handshake [length 04ba], ServerHello
>>> TLS 1.3, Handshake [length 0132], ClientHello
<<< TLS 1.3, Handshake [length 007a], ServerHello

Soit 1484 octets contre 306 pour le ClientHello, et 1210 contre 122 pour le ServerHello. Les ClientHello plus volumineux ont révélé des bugs dans des serveurs et des équipements intermédiaires qui supposaient que le message arrivait en une seule lecture TCP ou dans un seul paquet ; lorsque Chrome a activé par défaut les key shares hybrides Kyber dans sa version 124 (2024), plusieurs pare-feu et proxys ont dû être corrigés, une classe de problèmes documentée sur tldr.fail. Cloudflare et Google ont mesuré, du fait des octets supplémentaires, une hausse de quelques pour cent de la latence médiane du handshake, ce qui pèse bien moins que les allers-retours économisés par TLS 1.3 lui-même.

État du déploiement

  • Navigateurs : Chrome et Edge proposent X25519MLKEM768 par défaut depuis la version 131 (novembre 2024), Firefox depuis la 132 sur ordinateur, Safari et la pile TLS système d’Apple depuis iOS 26 et macOS 26 (2025). La variante pré-standard X25519Kyber768Draft00 (0x6399) qu’ils utilisaient auparavant est obsolète.
  • Bibliothèques : OpenSSL 3.5 (avril 2025) envoie par défaut des key shares X25519MLKEM768 et X25519 ; Go 1.24 l’active par défaut dans crypto/tls ; le JDK 27 (septembre 2026, JEP 527) le propose en premier par défaut ; BoringSSL, rustls et NSS le prennent en charge.
  • Serveurs et CDN : Cloudflare, Google et d’autres grands fournisseurs le négocient avec les clients compatibles ; nginx, Apache et HAProxy en bénéficient via l’OpenSSL auquel ils sont liés.
  • SSH : l’équivalent mlkem768x25519-sha256 est l’algorithme par défaut d’OpenSSH depuis la version 10.0 (RFC 10042).

Le test TLS post-quantique du navigateur montre ce que négocie votre propre navigateur.

Quand choisir l’un ou l’autre

  • HTTPS public et API : proposez X25519MLKEM768 en premier et X25519 en second ; tout client moderne négocie l’hybride, et les anciens se replient sur X25519.
  • Maillage de services interne et mTLS : hybride par défaut, en particulier pour les données soumises à de longues exigences de confidentialité.
  • Déploiements orientés FIPS : SecP256r1MLKEM768 ou SecP384r1MLKEM1024 si la liste approuvée de votre module exige des courbes NIST ; X25519MLKEM768 convient lorsque ML-KEM est le composant approuvé.
  • Liaisons contraintes où chaque paquet compte : mesurez d’abord ; l’hybride ajoute un paquet dans chaque sens, ce qui est généralement acceptable.
  • X25519 seul : uniquement pour les pairs incapables d’utiliser l’hybride, jamais comme choix délibéré pour de nouveaux déploiements.

Notes de migration

  1. Mettez à jour la bibliothèque TLS (OpenSSL 3.5 ou ultérieur, Go 1.24 ou ultérieur, une version récente de BoringSSL ou de rustls) ; avec OpenSSL 3.5, les groupes par défaut incluent déjà l’hybride.
  2. Si vous définissez les groupes explicitement, ajoutez-le : par exemple ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1; dans nginx ou Groups = X25519MLKEM768:X25519:P-256 dans un fichier de configuration OpenSSL.
  3. Testez le chemin, pas seulement le serveur : les répartiteurs de charge, les WAF et les proxys qui inspectent TLS doivent gérer un ClientHello réparti sur plusieurs paquets et plusieurs lectures ; refaites les tests après leurs mises à jour.
  4. Vérifiez ce qui est négocié avec openssl s_client -groups X25519MLKEM768 ou les outils de développement du navigateur, et surveillez la part des handshakes hybrides.
  5. Planifiez séparément le volet signature : l’hybride ne protège que la confidentialité ; les certificats et les signatures du handshake restent classiques jusqu’à l’arrivée des signatures post-quantiques dans la WebPKI.

Références

Tous les comparatifs