Savez-vous comment marche le mécanisme de la confiance dans une page web reçue avec HTTPS ? Petit tour rapide et présentation de Let's Encrypt.
Si vous êtes un lecteur régulier du site, vous savez que le chiffrement de bout en bout est un dada chez moi, plutôt que le chiffrement point-à-point. On n'a pas encore fait de glossaire, donc je vais le réexpliquer à cette occasion, mais on finira par se référer à un petit manuel de bases. Donc si vous connaissez, vous pouvez zaper la partie 0 qui suit.
- le chiffrement de bout en bout signifie que votre ordinateur chiffre avec la clef de votre correspondant, et par conséquent sur le réseau, le message est toujours chiffré ;
- le chiffrement point à point est appliqué entre vous et votre pair direct, puis (éventuellement) votre pair chiffre avec son pair, etc. jusqu'à destination, le message peut donc :
- traverser un bout du réseau sans chiffrement ;
- être lu par tous les pairs qui ont acheminé le message.
- En comparaison, c'est comme si une lettre à La Poste était lu par tous ceux qui l'ont en main, et que de temps en temps le service de poste était négligent, et laissait à tous la possibilité de lire la lettre.
Sur internet vous utilisez les deux :
- le mail utilise le chiffrment point à point (sur lequel vous pouvez rajouter du chiffrement de bout en bout avec GPG/PGP) ;
- parler HTTPS avec un serveur permet de récupérer une page qui sera chiffrée entre vous et le serveur, donc d'un bout du réseau à l'autre.
HTTP est un protocole qui permet de récupérer des pages web. Exemples de ce qu'on peut "dire en HTTP" :
- quand on est le client :
- donne moi la page à cette URL ;
- quand on est le serveur :
- la page que tu m'as demandé, je l'ai, la voici ;
- la page que tu m'as demandé, je l'ai, mais attends un peu, je suis surbooké, là (schématiquement) ;
- la page que tu m'as demandé, bah elle existe pas (404) ;
- ce que tu demandes n'est pas ici, va voir ailleurs (301) ;
- j'ai pas compris ce que tu m'as demandé (400) ;
- ce que tu fais-là, tu n'en as pas le droit (403) ;
- le serveur est en panne (503)...
Et beaucoup d'autres. HTTPS n'est que l'utilisation d'une couche de chiffrement (SSL/TLS) pour chiffrer les données :
- la requête (pas celles initiant le chiffrement) ;
- les données échangées par la suite.
Pour visualiser la couche de chiffrement, on peut se représenter un tunnel entre le client et le serveur dans lequel la donnée passe. Personne ne peut accéder à l'intérieur du tunnel parce qu'il est solide, et le tunnel a une entrée (le client) et une sortie (le serveur).
Lorsqu'Alice va demander la page web de Bob en HTTPS, que va-t-il se passer ?
- Le client A (son navigateur web Firefox) va faire une requête vers un serveur B
- B qui va indiquer qu'il sait parler HTTPS ;
- A va interroger B ;
- B va répondre, et s'il a la page, la transmettre.
Tout ça s'est fait automatiquement. Voyons un peu l'architecture de chiffrement mise en place ici. Il s'agit d'une infrastructure clef publique/clef privée + autorité de confiance :
- A va obtenir via le réseau la clef publique de B.
- Le navigateur web de A va vérifier que la clef est valide, c'est à dire qu'il s'agit bien de la bonne clef (et pas celle d'un attaquant) et qu'elle est toujours valide (par mesure de sécurité, les clefs ont une durée de validité, d'un an en général).
- A va chiffrer ses messages pour B avec la clef publique de B.
- B déchiffre ses messages avec sa clef privée.
Ainsi, la confiance que l'on a dans HTTPS dépend de deux facteurs :
- comment le navigateur reconnait qu'un certificat est valide ;
- la qualité du chiffrement, _ie_ les algorithmes utilisés (RC4 : mauvais, AES-256 très bon, à ce jour).
On ne parlera pas plus des algorithmes ici, à la place on se concentrera sur comment le navigateur a décidé de reconnaître un certificat, ou de l'invalider.
Le problème de fond, c'est de reconnaître la validité d'une clef de chiffrement (publique) pouvant changer fréquemment obtenue via internet.
On utilise ce qu'on appelle un pair de confiance. Si un certificat est signé par un pair de confiance, alors le certificat est considéré comme valide. Le pair de confiance dans l'architecture X509 s'appelle une autorité de certification (AC, parce que j'ai pas envie de le réécrire ;) ). Par défaut Firefox fait donc confiance à un certaint nombre d'AC.
Ainsi lorsqu'une clef publique arrive depuis internet :
- si le certificat est signé par une AC, il est valide (sauf cas exceptionnel où l'utilisateur a interdit le certificat) ;
- si le certificat n'est pas signé par une AC, mais est accepté par l'utilisateur, il est valide ;
- le reste **poubelle**, la connexion est terminée.
Dans les AC vous en connaissez peut-être quelques unes dont Thawte, VeriSign, GoDaddy, CA-Cert, Gandi, Google (eh oui, il font ça aussi), et depuis peu Let's Encrypt.
Mais la chaîne de confiance n'est pas complète. Comment savoir quelles sont les entités reconnues, comment en rajouter sans mettre à jour tous les navigateurs ?
Eh bien à la base de la création de X509, on a généré une clef c0, et une clef c1, on a signé la clef c1 avec la clef c0 et découpé c0 en plusieurs (4 ?) parties qu'on a dispachées dans des coffres-forts. On fait donc en sorte que la clef 0 soit reconnue, et on signe les AC avec la clef c1. Les entités créent leur clef c\_entite (plusieurs en fait), qui est valide, puisque signée par c1, elle-même valide puisque signée par c0.
Récapitulons. On fait confiance à c0. c0 signe c1, de telle sorte que :
- c1 puisse signer des certificats ;
- c1 puisse signer des AC ;
On signe les AC, qui créent leur clefs, qui sont signées par c1 de telle sorte que :
- elles puissent signer des certificats ;
- éventuellement elles puissent signer d'autres AC.
Ainsi, la chaîne de confiance est une hiérarchie. Faire confiance à c0 permet/implique a priori de faire confiance à beaucoup de gens (on peut cependant demander à Firefox de ne pas accepter un certificat valide).
Vous avez peut-être remarqué que c0 ne sert qu'à signer c1, puis on demande au navigateur de reconnaître c0, puis on signe avec c1.
Vous vous demandez peut être pourquoi... Imaginons que c0 = c1 = c$latex \\alpha $, c'est à dire qu'au début de la chaîne de confiance il y ait non pas deux mais une seule clef c$latex \\alpha $.
Un problème se pose, et a pas mal de répercussions :
Si la clef $latex \\alpha $ est perdue alors toute la sécurité de l'architecture X509 s'effondre.
- Dans le cas où on n'a qu'une clef c$latex \\alpha $, on ne peut rien faire.
- Dans le cas ou on a c0 et c1, et c1 est perdue (on suppose que c0 n'est pas perdue, elle sous clef, éparpillée sur le globe), on révoque c1 à l'aide de c0, et on regénère une clef c1'. Ça permet notamment de pouvoir rapidement recréer un environnement de confiance, et de ne pas avoir besoin de rediffuser la clef à toutes les machines.
Alors pourquoi est-ce que je vous rabats les oreilles avec tout ça ? Eh bien pour deux raisons :
- d'abord pour que vous sachiez quelle confiance accorder dans des connexions HTTPS ;
- ensuite pour vous parler spécialement d'une AC : Let's Encrypt.
Vous l'avez compris, il y a beaucoup d'enjeux concernant une AC. La confiance qu'on a, la qualité de son travail, de la façon dont elle sécurise ses données pour ne pas perdre sa clef et servir de vecteur d'attaque, etc. Il y a d'autres enjeux dont la possibilité pour tous de chiffrer facilement, en effet les certificats ne sont pas gratuits, sauf certains de CA-Cert, et de Gandi.
C'est pourquoi Mozilla Cisco l'EFF et d'[autres](https://letsencrypt.org/) se sont unis pour créer une AC dont le but serit de permettre à tous de pratiquer le chiffrement à tour de bras. Et [voilà qui est fait](https://letsencrypt.org/2015/10/19/lets-encrypt-is-trusted.html).
Depuis le 19 octobre 2015 les certificats de Let's Encrypt sont de confiance par défaut dans les versions récentes de Firefox (probablement Chrome/Chromium, Microsoft Edge, et Safari).
Let's Encrypt va donc pouvoir se mettre à un rythme de croisière de signatures de certificats d'ici très peu de temps.