SSL est le nom le plus souvent utilisé pour désigner ce protocole, mais SSL fait spécifiquement référence au protocole propriétaire conçu par Netscape au milieu des années 90. « TLS » est une norme de l’IETF basée sur SSL, c’est pourquoi je vais parler de TLS. De nos jours, il y a de fortes chances que la quasi-totalité de vos connexions sécurisées sur le web utilisent en réalité TLS, et non SSL.
TLS a plusieurs capacités :
- Crypter les données de votre couche d’application. (Dans notre cas, le protocole de la couche application est HTTP).
- Authentifier le serveur auprès du client.
- Authentifier le client auprès du serveur.
#1 et #2 sont très courants. #Le n°3 est moins courant. Nous nous concentrer ici sur le n°2.
Authentification
Un serveur s’authentifie auprès d’un client à l’aide d’un certificat. Un certificat est un blob de données[1] qui contient des informations sur un site web :
- Nom de domaine
- Clé publique
- L’entreprise qui le possède
- La date d’émission du certificat
- Quand il expire
- Qui l’a émis
- Etc.
Vous pouvez assurer la confidentialité (n° 1 ci-dessus) en utilisant la clé publique incluse dans le certificat pour chiffrer les messages qui ne peuvent être déchiffrés que par la clé privée correspondante, qui doit être stockée en toute sécurité sur ce serveur[2] Appelons cette paire de clés KP1, afin d’éviter toute confusion ultérieure. Vous pouvez également vérifier que le nom de domaine figurant sur le certificat correspond au site que vous visitez (point 2 ci-dessus).
Mais que se passe-t-il si un adversaire peut modifier les paquets envoyés et reçus par le serveur, et si cet adversaire modifie le certificat qui vous a été présenté et insère sa propre clé publique ou change tout autre détail important ? Si cela se produisait, l’adversaire pourrait intercepter et modifier tous les messages que vous pensiez être cryptés en toute sécurité.
Pour éviter cette attaque, le certificat est signé de manière cryptographique par la clé privée d’une autre personne, de telle sorte que la signature puisse être vérifiée par toute personne possédant la clé publique correspondante. Appelons cette paire de clés KP2, pour bien montrer qu’il ne s’agit pas des mêmes clés que celles utilisées par le serveur.
Autorités de certification
Alors qui a créé KP2 ? Qui a signé le certificat ?
En simplifiant un peu, une autorité de certification crée KP2 et vend le service consistant à utiliser sa clé privée pour signer des certificats pour d’autres organisations. Par exemple, je crée un certificat et je paie une société comme Verisign pour le signer avec sa clé privée[3]. Comme personne d’autre que Verisign n’a accès à cette clé privée, personne ne peut falsifier cette signature.
Et comment pourrais-je personnellement mettre la main sur la clé publique de KP2 afin de vérifier cette signature ?
Nous avons déjà vu qu’un certificat peut contenir une clé publique – et les informaticiens adorent la récursion – alors pourquoi ne pas mettre la clé publique de KP2 dans un certificat et le distribuer de cette façon ? Cela semble un peu fou au premier abord, mais en fait c’est exactement comme cela que cela fonctionne. Pour reprendre l’exemple de Verisign, Verisign produit un certificat qui contient des informations sur son identité, les types de documents qu’il est autorisé à signer (autres certificats) et sa clé publique.
Si j’ai une copie de ce certificat Verisign, je peux l’utiliser pour valider la signature du certificat du serveur du site Web que je veux visiter. Facile, non ?
Eh bien, pas si vite. Je devais obtenir le certificat Verisign quelque part. Et si quelqu’un falsifiait le certificat Verisign et y mettait sa propre clé publique ? Il peut alors falsifier la signature du certificat du serveur, et nous revoilà au point de départ : une attaque de type « man-in-the-middle ».
Chaînes de certificats
En continuant à penser de manière récursive, nous pourrions bien sûr introduire un troisième certificat et une troisième paire de clés (KP3) et les utiliser pour signer le certificat Verisign. Nous appelons cela une chaîne de certificats : chaque certificat de la chaîne est utilisé pour vérifier le certificat suivant. J’espère que vous avez déjà compris que cette approche récursive n’est qu’une succession de tortues/certificats. Où s’arrête-t-elle ?
Puisque nous ne pouvons pas créer un nombre infini de certificats, la chaîne de certificats doit évidemment s’arrêter quelque part, et c’est ce que nous faisons en incluant un certificat auto-signé dans la chaîne.
Confiance conférée
L’authentification dans TLS utilise un système de confiance conférée. Si je veux engager un mécanicien automobile, je peux ne pas faire confiance à n’importe quel mécanicien que je trouve au hasard. Mais peut-être que mon ami se porte garant d’un mécanicien particulier. Puisque j’ai confiance en mon ami, je peux faire confiance à ce mécanicien.
Lorsque vous achetez un ordinateur ou téléchargez un navigateur, il est livré avec quelques centaines de certificats racine auxquels il fait explicitement confiance[4]. Les entreprises qui possèdent et exploitent ces certificats peuvent conférer cette confiance à d’autres organisations en signant leurs certificats.
Ce système est loin d’être parfait. Il arrive parfois qu’un CA émet un certificat par erreur. Dans ce cas, le certificat doit être révoqué. La révocation est délicate car le certificat émis sera toujours correct d’un point de vue cryptographique ; un protocole hors bande est nécessaire pour déterminer quels certificats précédemment valides ont été révoqués. Dans la pratique, certains de ces protocoles ne sont pas très sûrs, et de nombreux navigateurs ne les vérifient pas de toute façon.
Parfois, un CA entier est compromis. Par exemple, si vous vous introduisez dans Verisign et volez leur clé de signature racine, vous pouvez falsifier n’importe quel certificat dans le monde. Notez que cela n’affecte pas seulement les clients de Verisign : même si mon certificat est signé par Thawte (un concurrent de Verisign), cela n’a aucune importance. Mon certificat peut toujours être falsifié en utilisant la clé de signature compromise de Verisign.
Ce n’est pas seulement théorique. Cela s’est produit dans la nature. DigiNotar a fait l’objet d’un piratage célèbre et a ensuite fait faillite. Comodo a également été piraté, mais inexplicablement, il est toujours en activité à ce jour.
Même lorsque les CAs ne sont pas directement compromis, d’autres menaces pèsent sur ce système. Par exemple, un gouvernement peut utiliser la coercition légale pour obliger un CA à signer un faux certificat. Votre employeur peut installer son propre certificat de CA sur l’ordinateur de votre employé. Dans ces différents cas, le trafic que vous pensez être « sécurisé » est en fait complètement visible/modifiable par l’organisation qui contrôle ce certificat.
Conclusion
[1] Les données des certificats TLS sont formatées conformément à la norme X.509. X.509 est basé sur ASN.1 (« Abstract Syntax Notation #1 »), ce qui signifie que ce n’est pas un format de données binaire. Par conséquent, X.509 doit être encodé dans un format binaire. DER et PEM sont les deux encodages les plus courants à ma connaissance.
[2] En pratique, le protocole passe à un chiffrement symétrique, mais c’est un détail qui n’est pas pertinent pour votre question.
[3] On peut supposer que l’autorité de certification valide réellement votre identité avant de signer votre certificat. Si ce n’était pas le cas, je pourrais simplement créer un certificat pour google.com et demander à une autorité de certification de le signer. Avec ce certificat, je pourrais m’immiscer dans n’importe quelle connexion « sécurisée » vers google.com. Par conséquent, l’étape de validation est un facteur très important dans le fonctionnement d’une AC. Malheureusement, la rigueur de ce processus de validation n’est pas très claire pour les centaines d’AC dans le monde.
[4] Voir la liste des autorités de certification de confiance de Mozilla.
Comment la connexion HTTPS est-elle établie entre le navigateur et le serveur web ?
- Le navigateur essaie de se connecter à l’adresse https://payment.com.
- Le serveur payment.com envoie un certificat au navigateur. Ce certificat comprend la clé publique du serveur payment.com, et des preuves que cette clé publique appartient effectivement à payment.com.
- Le navigateur vérifie le certificat pour confirmer qu’il possède la bonne clé publique pour payment.com.
- Le navigateur choisit une nouvelle clé symétrique aléatoire K à utiliser pour sa connexion au serveur payment.com. Il crypte K sous la clé publique de payment.com.
- payment.com déchiffre K en utilisant sa clé privée. Maintenant, le navigateur et le serveur de paiement connaissent tous deux K, mais personne d’autre ne le connaît.
- Chaque fois que le navigateur veut envoyer quelque chose à payment.com, il le crypte sous K ; le serveur payment.com le décrypte à la réception. Chaque fois que le serveur de paiement.com veut envoyer quelque chose à votre navigateur, il le crypte sous K.
Ce flux peut être représenté par le schéma suivant :
