Décoder l'extension TLS Encrypted Client Hello

Traductions

Sommaire

Dans cet article, je vous propose de découvrir Encrypted Client Hello (ECH), une extension du protocole réseau Transport Layer Security (TLS) visant à garantir plus de vie privée. Le principe est de rendre illisibles pour une personne non-autorisée certaines informations de navigation Web transitant sur Internet.

Introduction

Les communications Web via le protocole HyperText Transfer Protocol (HTTP) sont aujourd’hui chiffrées à hauteur d’environ 95% (selon Google et Cloudflare). Cela est rendu possible grâce au protocole Transport Layer Security (TLS). Ce dernier permet de chiffrer et authentifier des sessions dans lesquelles des données en clair peuvent circuler avec un meilleur niveau de sécurité (confidentialité et intégrité) sur un réseau de moindre confiance comme Internet. Bien que considéré robuste dans sa dernière version et très largement adopté, des informations sensibles circulent encore en clair avec ce protocole et cela peut être considéré comme un problème de vie privée ou Privacy. Pour pallier cela, une solution est en cours de standardisation : Encrypted Client Hello (ECH). Nous allons voir pourquoi TLS montre actuellement des limites quant à la vie privée, puis voir le fonctionnement de la solution ECH mais aussi en quoi ECH lève de nouvelles problématiques de sécurité.

Les limites de TLS 1.3

Le protocole TLS est apparu en 1994 sous sa première version : SSL 1.0. Il a ensuite évolué avec SSL 2.0, SSL 3.0, TLS 1.0, TLS 1.1, TLS 1.2 et enfin TLS 1.3. Il se décompose sur deux sous-protocoles :

  • Le Handshake Protocol, qui permet d’authentifier le serveur et éventuellement le client et négocier les paramètres cryptographiques.
  • Le Record Protocol, qui permet le chiffrement, la fragmentation, la transmission, la vérification, le déchiffrement et le réassemblage des messages.

Echange protocolaire TLS 1.3

Avec la dernière version, TLS 1.3, de nouvelles fonctionnalités significatives furent apportées par rapport aux versions précédentes. On peut citer notamment :

  • le retrait des algorithmes dépréciés de chiffrement symétrique, de Hash-based Message Authentication Code (HMAC, technique visant à authentifier un message à partir d’une clé de chiffrement et d’une fonction de hachage cryptographique) et de signatures ;
  • le retrait des mécanismes d’échange de clés statiques sans Forward Secrecy ;
  • le support des algorithmes utilisant les courbes elliptiques ;
  • l’utilisation des fonctions de dérivation de clés à base de HMAC ou HMAC-based Key Derivation Function (HKDF, fonction de dérivation de clés reposant sur HMAC) ;
  • la reprise de sessions plus rapide avec des clés partagées ou Pre-Shared Key (PSK) ;
  • la protection contre le rétrogradage cryptographique par calcul d’un Message Authentication Code (MAC, objet utilisé pour assurer l’intégrité d’un message) des messages de négociation protocolaire ;
  • la réduction du nombre de paquets échangés (Zero Round-Trip-Time ou 0-RTT) dans le Handshake Protocol accélérant la connexion ;
  • le chiffrement de plus de méta-données dans le Handshake Protocol.

Malgré tout, dans TLS 1.3, il est encore possible d’utiliser une extension appelée Server Name Indication (SNI). Cette extension est passée en clair avec le premier paquet ClientHello et permet au client d’indiquer au serveur le nom de domaine vers lequel il essaye de se connecter. Le serveur, pouvant héberger potentiellement plusieurs services et noms de domaines (on parle de virtual hosting), peut alors choisir le bon certificat TLS associé. En outre, les systèmes de filtrage Web sur le réseau, comme les proxys ou les pare-feux de nouvelle génération, utilisent la valeur du SNI pour décider d’autoriser ou non la connexion TLS dont le contenu est illisible pour ces équipements.

Exemple d'utilisation du Server Name Indication

Aussi, une autre extension est passée en clair : Application-Layer Protocol Negotiation (ALPN). Cette extension permet au client, dans le paquet TLS ClientHello, d’indiquer quels protocoles applicatifs sont supportés et au serveur de choisir l’un deux et l’indiquer dans le paquet de réponse ServerHello. Cela permet au serveur de retourner là aussi le bon certificat s’il en dispose de plusieurs selon l’application. Cela permet par exemple de négocier l’utilisation de HTTP/2 au profit d’HTTP/1.1.

Enfin, un autre point essentiel est qu’avant d’établir une connexion TLS, le client doit généralement d’abord effectuer une requête Domain Name System (DNS) afin de déterminer l’adresse Internet Protocol (IP) à contacter à partir d’un nom de domaine. Ces requêtes circulent par défaut en clair sur le réseau.

Ces pratiques (SNI, ALPN, DNS) sont essentielles, mais générant des transferts de données en clair, elles divulgent des informations pouvant compromettre la vie privée des utilisateurs. Plusieurs initiatives ont pour but de masquer le transfert de telles informations. On peut notamment citer :

  • DNS-over-TLS (DoT), qui consiste à faire passer les requêtes DNS dans une session chiffrée TLS.
  • DNS-over-HTTPS (DoH), qui consiste à faire passer les requêtes DNS dans le protocole HTTP lui même encapsulé dans TLS.
  • DNS-over-QUIC (DoQ), qui consiste à faire passer les requêtes DNS dans le protocole QUIC (protocole de transport construit sur le protocole User Datagram Protocol ou UDP).
  • Encrypted SNI (ESNI), qui consiste à chiffrer le SNI au sein du paquet TLS ClientHello. Elle a été abandonnée au profit d’ECH, qui pourrait bien être plus massivement adoptée.

Récapitulatif des initiatives réseau pour la navigation privée

Une autre initiative, ECH, a commencé à voir le jour en 2018 et est encore à ce jour en cours de standardisation. Elle est une amélioration de l’initiative ESNI dans le sens où elle s’attache à masquer non pas seulement le SNI mais un ensemble d’informations contenu dans le paquet ClientHello.

Fonctionnement d’ECH

ECH est une extension du protocole TLS 1.3 qui consiste à communiquer les informations sensibles du paquet ClientHello de manière chiffrée. Pour arriver à cela, le principe est pour le client de récupérer en amont des informations cryptographiques regroupées dans une configuration ECH publiée par le serveur, puis de les utiliser afin de construire un paquet TLS 1.3 ClientHello contenant en fait deux versions du paquet : une publique, en clair, et une privée, chiffrée.

ECH repose sur le récent standard Hybrid Public Key Encryption (HPKE) pour effectuer le chiffrement et déchiffrement (appelés encapsulation et décapsulation en termes HPKE) de la version privée du ClientHello. Je ne vais pas détailler HPKE dans cet article et préfère vous rediriger vers le standard ou ce très bon article. Dans les grandes lignes, HPKE permet, via un Key Encapsulation Mechanism (KEM), de transmettre une clé de chiffrement symétrique encapsulée (chiffrée) via une clé publique asymétrique, puis de la décapsuler (déchiffrer) via la clé privée asymétrique associée. Pour plus d’informations sur les concepts de chiffrement symétrique et asymétrique, je vous renvoie vers un autre de mes articles.

Récupération de la configuration ECH

Une configuration ECH contient notamment un identifiant, une clé publique HPKE, une suite cryptographique ou cipher suite (ensemble d’algorithmes cryptographiques) et un nom de domaine public. Pour partager la configuration ECH aux clients, le serveur utilise généralement un autre protocole : le DNS. En effet, au-délà de la résolution de noms de domaines, DNS est très utilisé pour partager des informations d’infrastructure sur le réseau. ESNI utilisait des enregistrements DNS de type TXT ou type 16 pour partager les clés publiques servant à chiffrer le SNI. Ce type d’enregistrement sert à stocker des informations sous forme textuelle. Voici un exemple de requête DNS TXT effectuée avec l’outil dig.

$ dig +short txt.thibautprobst.fr txt
"This is a nice TXT record!"

Avec ECH, la configuration est rendue disponible via un enregistrement DNS de type HTTPS Resource Record (RR) ou type 65. Ce type d’enregistrement DNS sert à stocker des informations pour délivrer des configurations spécifiques à un service accédé via le protocole HTTPS. Voici un exemple lorsqu’on cherche à récupérer la configuration ECH de crypto.cloudflare.com :

$ dig +short crypto.cloudflare.com HTTPS
1 . alpn="http/1.1,h2" ipv4hint=162.159.137.85,162.159.138.85 ech=AEX+DQBBNQAgACAeSM3dLHfo+RGkgUXbBhzqU65l5T7hjuGv4Sz7ztXeaAAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA= ipv6hint=2606:4700:7::a29f:8955,2606:4700:7::a29f:8a55

Si on regarde le paquet DNS associé, on retrouve toutes les informations de la configuration ECH :

Paquet DNS de réponse HTTPS RR pour ECH

Les configurations ECH sont alors généralement récupérées via DoH ou DoT afin de garantir la confidentialité de ces échanges-là et ainsi ne pas divulguer plus d’informations sur les intentions d’utiliser ECH.

Construction et envoi du ClientHello

Si aucune configuration ECH ne peut être récupérée en amont de la communication Web, cela peut être préconfiguré sur le client. Il est à noter que si ce dernier n’a pas de configuration ECH disponible, il doit malgré tout envoyer un paquet TLS ClientHello où il y construit une extension ECH au format adéquat mais avec des valeurs aléatoires et appelée Generate Random Extension And Sustain Extensibility (GREASE). Cela permet au client d’indiquer sa volonter d’utiliser ECH et maintenir l’intéropérabilité même si le serveur va l’ignorer.

Sinon, si la configuration ECH a pu être récupérée, le paquet TLS ClientHello est construit ainsi :

  • Une section ClientHelloOuter incluant un SNI en version publique (ne révélant pas d’information directe sur le serveur Web destination) et une extension ECH avec notamment les champs suivants :
    • un type de ClientHello : ici outer ;
    • l’identifiant de la configuration ECH ;
    • une suite cryptographique ou cipher suite ;
    • la clé HPKE encapsulée grâce à la clé publique et qui servira à déchiffrer le champ suivant ;
    • une charge utile ou payload qui correspond au ClientHelloInner chiffré avec la clé publique ECH ainsi que des données additionnelles authentifiées ou Additional Authenticated Data (AAD).
  • Une section ClientHelloInner qui est la portion chiffrée de l’extension ECH du ClientHelloOuter. Il s’agit d’un deuxième paquet ClientHello contenu dans le premier, où le SNI est en version privée (la valeur associée au serveur Web destination).

Paquet TLS ClientHello ECH

Acceptation ou rejet d’ECH

A réception du paquet ClientHello ECH, le serveur peut agir de deux manières selon le type ClientHello:

  • S’il est de type outer :
    • Si le serveur supporte ECH, il vérifie le ClientHelloOuter puis essaye d’extraire le ClientHelloInner en le déchiffrant avec sa clé privée. Il transmet ensuite le ClientHelloInner au serveur de destination (qui peut éventuellement être lui-même). C’est une acceptation d’ECH.
    • Si en revanche le serveur ne supporte pas ECH, il fait la négociation avec le ClientHelloOuter. C’est un rejet d’ECH.
  • S’il est de type inner, le serveur envoie une réponse TLS classique du type ServerHello, à l’exception du champ random qui est dérivé du champ random du paquet ClientHelloInner reçu. Le serveur peut aussi répondre avec un paquet de type HelloRetryRequest contenant une extension ECH indiquant une acceptation d’ECH avec une demande de renvoie de paquet ECH ClientHello car il lui a fourni dans ce cas une configuration ECH. Si le message HelloRetryRequest ne contient pas d’extension ECH, cela correspond à un rejet d’ECH.

Dans le document de standardisation, une dissociation théorique est faite entre le serveur traitant le ClientHelloOuter (appelé le client-facing server) et celui traitant le ClientHelloInner (appélé le backend server).

Bien entendu, il est à noter aussi qu’avec ECH, le serveur n’acceptera que du TLS en version 1.3 ou supérieure.

Tester ECH

Dans cette section, je vous propose de tester ECH et d’en véfifier le fonctionnement. Pour ce faire, à l’écriture initiale de cet article, j’utilise le navigateur Mozilla Firefox en version 120 (où ECH est activé par défaut, la version minimale requise pour ECH étant 118) sur MacOS Ventura en version 13.3.1. Mozilla Firefox s’appuye sur DoH pour récupérer les configurations ECH.
Dans Firefox, dans la barre d’adresse, tapez about:preferences, allez dans Privacy and Security et dans la section DNS over HTTPS, choisissez Increased Protection (vous pouvez laisser Cloudflare en fournisseur par défaut).

Première étape de la configuration ECH pour Firefox

Ensuite, dans la barre d’adresse, entrez about:config puis dans la barre de recherche tapez network.dns.echconfig.enabled et assurez vous que l’entrée network.dns.echconfig.enabled est positionnée à true.

Deuxième étape de la configuration ECH pour Firefox

Ensuite, avec Mozilla Firefox, naviguez vers un site Web supportant ECH comme par exemple https://tls-ech.dev ou https://crypto.cloudflare.com/cdn-cgi/trace qui vous diront alors explicitement dans la page HTML de réponse si vous utilisez ECH ou si le SNI est chiffré.
Si on regarde une capture de paquet associée, on retrouve dans l’en-tête TLS le SNI public (ici public.tls-ech.dev) et l’extension ECH contenant les champs que nous avons évoqués plus tôt.

Capture d'un paquet ECH

Les problématiques d’ECH

Avec ECH, les mécanismes de sécurité des réseaux tels que les proxys, pare-feux de nouvelle génération ou autre Web Applications Firewall (WAF) se retrouveront dans l’impossibilité d’effectuer du filtrage d’Uniform Resource Locator (URL), de la réputation de sites Web ou même du déchiffrement de flux TLS. En effet, l’incapacité de lire le SNI dans le ClientHelloInner rend ces mécanismes aveugles quant à la destination des flux et ainsi la décision de filtrage ou déchiffrement impossible. Cela peut donc baisser le niveau de sécurité d’une organisation ou la conformité vis-à-vis de recommendations de services ou autorités administatifs quant à la traçabilité des accès Internet.
Voici les deux solutions que j’entrevois à l’heure actuelle :

  • Bloquer ECH (aussi éventuellement DoH et DoT) dans les milieux d’entreprise, soit au niveau des navigateurs Web, soit au niveau du réseau.
  • Mettre en place un proxy transparent ou reverse proxy capable d’accepter et négocier ECH pour un ensemble de sites Web donnés. Une bonne base pour aller à l’échelle pourrait être les Content Delivery Networks (CDN) désormais très présents sur Internet.

Conclusion

ECH est une extension de TLS en cours de standardisation visant à garantir un maximum de vie privée lors connexions sécurisées sur Internet. Pour cela, le SNI et d’autres paramètres sont chiffrés dans le paquet d’initiation de connexion TLS en suivant le standard HPKE. Cela peut en revanche entraver le travail des mécanismes de filtrage Web et nous arrivons ainsi à un stade où vie privée et sécurité ont des intérêts opposés. Le déploiement à l’échelle d’ECH reste aujourd’hui en travaux du fait des tâches techniques à compléter pour y parvenir et des contraintes des mécanismes de filtrage. Affaire à suivre !

Sources

Traductions