Le protocole SSL (Secured Socket Layer) a été conçu pour assurer une communication confidentielle et fiable entre deux applications et pour identifier le serveur et parfois le client. Ce protocole a été repris et légèrement modifié par l’IETF (RFC 2246) sous le nom de TLS (Transport Layer Security). Le terme SSL désigne communément les protocoles SSL version 3 ou TLS. Le protocole SSL nécessite un protocole de transport sûr (par exemple TCP) pour la transmission et la réception de données.
Le protocole est composé de deux couches. Au niveau le plus bas, juste au dessus d’un protocole de transport sûr, se trouve le SSL Record Protocol. Celui-ci est utilisé pour encapsuler d’autres protocoles de plus haut niveau tel le SSL Handshake Protocol qui permet au serveur et au client de s’authentifier et de négocier un algorithme de chiffrement et des clés cryptographiques communes avant que le protocole d’application ne reçoive son premier octet d’information.
Le positionnement du protocole SSL dans le modèle OSI peut être schématisé comme suit :
Figure 49 : Positionnement des protocoles SSL au sein du modèle OSI
Un protocole d’application de « niveau supérieur » peut ainsi se placer au dessus du protocole SSL de manière transparente (par exemple HTTP, FTP, TELNET,...). Le protocole SSL assure un « canal de sécurité » dont les trois propriétés principales sont :
- d’être un canal privé : tous les messages sont chiffrés ;
- d’être un canal authentifié : l’identité de « l’autre » peut être authentifiée en utilisant la cryptographie asymétrique ou à clé publique ;
- d’être un canal réputé sûr : le transport du message inclut un message de vérification d’intégrité (Message Authentication Code, MAC).
Dans le cadre du protocole SSL, toutes les données envoyées sont encapsulées dans une structure RECORD composée d’une entête et d’une certaine quantité de données. Chaque entête de la structure RECORD contient un code de longueur de deux ou trois octets.
L’entête de la structure RECORD définit une valeur appelée PADDING. La valeur du PADDING spécifie le nombre d’octets de données ajoutés à la structure originale par l’émetteur. Les données tampon sont utilisées pour que la longueur de la structure soit un multiple de la taille de la clé employée dans le chiffrement.
Le destinataire de la structure déchiffre la structure de données entière de manière à avoir les données originales. Le destinataire extrait ensuite la valeur du PADDING pour déterminer la longueur réelle de la structure. Les données du PADDING sont ensuite éliminées.
La portion de données de la structure RECORD du SSL est composée de trois parties transmises et reçues dans l’ordre suivant :
- MAC-DATA : code d’authentification de message (Message Authentication Code) ;
- ACTUAL-DATA : données transmises ;
- PADDING-DATA : donnée tampon envoyée quand un bloc clé est utilisé.
Quand les structures SSL sont envoyées en clair, aucune clé n’est utilisée. Les valeurs des champs PADDING-DATA et MAC-DATA sont alors à zéro. Quand il y a chiffrement, ces valeurs changent selon certaines valeurs.
Le champ MAC-DATA est calculé par application d’une fonction de hachage sur les champs suivants :
- SECRET : champ dont la valeur dépend de la partie qui envoie le message. Dans le cas d’un message envoyé par le client, ce champ est mis à la valeur CLIENT-WRITE-KEY (le serveur utilisera SERVER-READ-KEY pour vérifier le MAC). Dans le cas d’un message reçu par le client, ce champ est mis à la valeur CLIENT-READ-KEY (le serveur utilisera SERVER-WRITE-KEY pour générer le MAC) ;
- ACTUAL-DATA ;
- PADDING-DATA ;
- SEQUENCE-NUMBER : compteur incrémenté par le client et le serveur à chaque envoi de messages. Le destinataire du message utilise la valeur attendue de SEQUENCE-NUMBER comme entrée de la fonction de hachage. Le MAC-DATA calculé doit correspondre bit à bit avec le MAC-DATA transmis. Si la comparaison n’est pas l’identité alors la structure est considérée endommagée et doit être traitée en erreur.
Le protocole Handshake SSL est utilisé pour négocier les attributs d’une session. Ce protocole comporte deux phases. La première phase sert à établir des communications privées. La seconde phase sert à l’authentification du client. Les messages constituant le protocole Handshake SSL doivent être présentés dans un ordre bien précis; dans le cas contraire, il en résulte une erreur fatale.
La première phase consiste à initier la communication en communiquant leurs « HELLO » respectifs. Le client entame la conversation en envoyant le message CLIENT-HELLO. Le serveur reçoit ce message et renvoie alors le message SERVER-HELLO. Arrivé à ce stade, le client et le serveur ont assez d’informations pour savoir s’ils ont besoin d’une clé maître. Quand une nouvelle clé maître n’est pas nécessaire, le serveur passe immédiatement à la phase 2.
Quand une nouvelle clé est exigée, le message SERVER-HELLO contiendra assez d’informations pour que le client la génère. Cela inclut le certificat signé du serveur, une liste de clés de chiffrement et une « connection-id » (valeur générée aléatoirement par le serveur et qui sera utilisée lors d’une seule connexion). Le client génère la clé maître et répond avec un message CLIENT-MASTER-KEY (ou un message d’erreur si le serveur indique que le client et le serveur ne sont pas d’accord sur la clé de chiffrement).
Finalement, le serveur envoie un message SERVER-VERIFY au client après que la clé maître ait été déterminée. La dernière étape identifie le serveur car uniquement le serveur qui a la clé publique appropriée peut connaître la clé maître.
La deuxième phase est la phase d’authentification. Le serveur a déjà été authentifié par le client dans la première phase et il ne reste qu’à authentifier le client. Sur requête du serveur, le client répondra s’il a l’information demandée.
Quand une des parties a authentifié l’autre, elle envoie son message d’arrêt. Pour le client, par exemple, le message CLIENT-FINISHED contient la forme chiffrée de « connection-id ». Si la vérification échoue, le serveur envoie un message d’erreur. Une fois qu’une partie a envoyé son message d’arrêt, elle doit continuer à écouter les messages du correspondant jusqu’à ce qu’elle reçoive un message d’arrêt. Dès qu’une partie a envoyé et reçu un message d’arrêt, le protocole handshake SSL est terminé et le protocole d’application commence à s’exécuter.
Les messages d’alarme communiquent la sévérité du message et une description de l’alarme. Le message d’alarme de niveau fatal conclut la connexion immédiatement. Dans ce cas, d’autres connexions correspondant à la session peuvent continuer mais l’identificateur de session doit être invalidé pour empêcher que la session défaillante soit utilisée pour établir de nouvelles connexions. Comme les autres messages, les messages d’alarme sont chiffrés.
Le client et le serveur doivent tous deux savoir que la connexion va se terminer de manière à éviter une attaque de coupure. N’importe laquelle des deux parties peut débuter l’échange des messages de fermeture en envoyant une alerte CLOSE_NOTIFY avant de fermer le côté écriture de la connexion. Il est nécessaire que l’autre partie réponde avec son propre CLOSE_NOTIFY et ferme la connexion immédiatement. Il n’est par contre pas nécessaire à l’initiateur de la fermeture d’attendre la réponse avant de fermer le côté lecture de la connexion. Toute information reçue après une alerte de fermeture est ignorée.
La gestion des erreurs dans le protocole de connexion SSL est très simple. Quand une erreur est détectée, la partie détectrice envoie un message à l’autre partie. Lors de la transmission ou de la réception d’un message d’alerte fatale, les deux parties ferment immédiatement la connexion. A la fois serveur et client sont censés oublier les identificateurs de session, les clés et les secrets associés à la connexion défaillante. Les erreurs sont donc irrécupérables. Le protocole Handshake SSL définit les erreurs suivantes :
- NO-CIPHER-ERROR : cette erreur est envoyée par le client au serveur quand il ne peut pas trouver une clé de chiffrement (problèmes de paramétrage) valable pour lui et le serveur ;
- NO-CERTIFICATE-ERROR : cette erreur est envoyée quand un client ne possède pas de certificat permettant de répondre à une requête REQUEST-CERTIFICATE ;
- BAD-CERTIFICATE-ERROR : cette erreur est renvoyée quand un certificat est jugé inadéquat (signature du certificat invalide, valeurs du certificat inappropriées) par le destinataire ;
- UNSUPPORTED-CERTIFICATE-TYPE-ERROR : cette erreur est envoyée quand le client ou le serveur reçoit un type de certificat qu’il ne peut accepter.
Il y a plusieurs messages qui sont générés uniquement par le client :
- CLIENT-HELLO (envoyé en clair en phase 1) contenant les informations suivantes :
ð MSG-CLIENT-HELLO ;
ð CLIENT-VERSION-MSB ;
ð CLIENT-VERSION-LSB ;
ð CIPHER-SPECS-LENGTH-MSB ;
ð CIPHER-SPECS-LENGTH-LSB ;
ð SESSION-ID-LENGTH-MSB ;
ð SESSION-ID-LENGTH-LSB ;
ð CHALLENGE-LENGTH-MSB ;
ð CHALLENGE-LENGTH-LSB ;
ð CIPHER-SPECS-DATA ;
ð SESSION-ID-DATA ;
ð CHALLENGE-DATA.
Lorsqu’un client se connecte à un serveur, le message CLIENT-HELLO est envoyé comme premier message. Le client envoie ainsi au serveur sa version de protocole SSL, sa clé de chiffrement, des données sur une session et quelques données supplémentaires. Les données d’identification de la session sont uniquement envoyées si le client a trouvé une session valable pour le serveur dans son cache. Si aucune session n’est trouvée, la valeur de SESSION-ID-LENGTH sera de zéro. Les données challenge sont utilisées pour authentifier le serveur.
Lorsque le serveur et le client se sont mis d’accord sur une paire de clés, le serveur renvoie un message SERVER-VERIFY avec la forme cryptée de CHALLENGE-DATA. De manière à permettre au serveur d’indiquer dans son premier message, l’état des sessions renvoyées par le client, le message SERVER-HELLO ne sera envoyé par le serveur qu’une fois le message CLIENT-HELLO reçu par celui-ci.
- CLIENT-MASTER-KEY (envoyé en clair en phase 1) contenant les informations suivantes :
ð MSG-CLIENT-MASTER-KEY ;
ð CIPHER-KIND (indique la clé de chiffrement choisie à partir du champ CIPHER-SPECS du serveur) ;
ð CLEAR-KEY-LENGTH-MSB ;
ð CLEAR-KEY-LENGTH-LSB ;
ð ENCRYPTED-KEY-LENGTH-MSB ;
ð ENCRYPTED-KEY-LENGTH-LSB ;
ð KEY-ARG-LENGTH-MSB ;
ð KEY-ARG-LENGTH-LSB ;
ð CLEAR-KEY-DATA (contient la portion en clair du champ MASTER-KEY. Le champ CLEAR-KEY-DATA est combiné avec le champ SECRET-KEY-DATA pour former le champ MASTER-KEY);
ð ENCRYPTED-KEY-DATA (contient les portions secrètes du champ MASTER-KEY (champ SECRET-KEY-DATA), chiffrées en utilisant la clé publique du serveur) ;
ð KEY-ARG-DATA.
Ce message est envoyé par le client une fois la clé maître déterminée (ce message n’est pas envoyé si les deux parties se sont déjà mises d’accord sur une clé de session).
- CLIENT-CERTIFICATE (envoyé en chiffré en phase 2) contenant les informations suivantes :
ð MSG-CLIENT-CERTIFICATE ;
ð CERTIFICATE-TYPE (en général ce champ est fixé à SSL_X509_CERTIFICATE) ;
ð CERTIFICATE-LENGTH-MSB ;
ð CERTIFICATE-LENGTH-LSB ;
ð RESPONSE-LENGTH-MSB ;
ð RESPONSE-LENGTH-LSB ;
ð CERTIFICATE-DATA (contient des données définies par la valeur du champ CERTIFICATE-TYPE. Dans le cas d’une valeur du champ CERTIFICATE-TYPE fixée à SSL_X509_CERTIFICATE, ce champ contient un certificat X509 signé) ;
ð RESPONSE-DATA.
Ce message est envoyé par un client en réponse au message REQUEST-CERTIFICATE du serveur.
- CLIENT-FINISHED (envoyé en chiffré en phase 2) contenant les informations suivantes :
ð MSG-CLIENT-FINISHED ;
ð CONNECTION-ID (contient l’identification originale de la session que le serveur envoie dans le message SERVER-HELLO).
Ce message est envoyé par le client pour terminer la procédure d’handshake SSL. Le client doit néanmoins continuer à écouter les messages provenant du serveur jusqu’à ce qu’il reçoive le message SERVER-FINISHED.
Le protocole d’handshake SSL implémente également un certain nombre de messages envoyés par le serveur.
- SERVER-HELLO (envoyé en clair en phase 1) contenant les informations suivantes :
ð MSG-SERVER-HELLO ;
ð SESSION-ID-HIT (champ booléen indiquant si l’identification de la session envoyé par le client est connue ou non du serveur. Si la valeur de ce champ est à zéro le serveur regroupe son certificat, ses paramètres algorithmiques et une identification de connexion pour l’envoyer au client. Si la valeur de ce champ est non nulle, le serveur et le client calculent à deux une nouvelle paire de clés pour la session en cours. Cette paire de clés provient du champ MASTER-KEY qui fut échangé quand la SESSION-ID fut créée) ;
ð CERTIFICATE-TYPE ;
ð SERVER-VERSION-MSB ;
ð SERVER-VERSION-LSB ;
ð CERTIFICATE-LENGTH-MSB ;
ð CERTIFICATE-LENGTH-LSB ;
ð CIPHER-SPECS-LENGTH-MSB ;
ð CIPHER-SPECS-LENGTH-LSB ;
ð CONNECTION-ID-LENGTH-MSB ;
ð CONNECTION-ID-LENGTH-LSB ;
ð CERTIFICATE-DATA ;
ð CIPHER-SPECS-DATA ;
ð CONNECTION-ID-DATA ;
Le serveur envoie ce message après avoir reçu le message CLIENT-HELLO du client. Le message SERVER-HELLO est envoyé après que le serveur ait reçu le message CLIENT-HELLO, et avant que le serveur n’envoie le message SERVER-VERIFY.
- SERVER-VERIFY (envoyé en chiffré en phase 1) contenant les informations suivantes :
ð MSG-SERVER-VERIFY ;
ð CHALLENGE-DATA ;
Le serveur envoie ce message après qu’une paire de clés (SERVER-READ-KEY et SERVER-WRITE-KEY) aient été trouvées. Le message contient une copie cryptée de CHALLENGE-DATA envoyé par le client dans son message CLIENT-HELLO.
Ce message est utilisé pour vérifier l’identité du serveur. Un serveur légitime devrait avoir la clé privée qui correspond à la clé publique contenue dans le certificat du serveur qui est transmis dans le message SERVER-HELLO. De cette façon, le serveur légitime serait capable d’extraire et de reconstruire la paire de clés de session (SERVER-READ-KEY et SERVER-WRITE-KEY). Finalement, seul un serveur qui a fait l’extraction et le déchiffrement proprement peut correctement chiffrer CHALLENGE-DATA. Ce mécanisme permet de prouver que le serveur a la clé privée correspondante à la clé publique contenue dans le certificat du serveur.
- SERVER-FINISHED (envoyé en chiffré en phase 2) contenant les informations suivantes :
ð MSG-SERVER-FINISHED ;
ð SESSION-ID-DATA (champ utilisé par le client et le serveur à ce moment pour ajouter des entrées à leurs caches respectives d’identification de sessions. Les caches doivent contenir une copie de MASTER-KEY envoyé dans le message CLIENT-MASTER-KEY) ;
Ce message est envoyé par le serveur pour terminer la procédure d’handshake SSL et indiquer qu’il est prêt à procéder à une transmission/réception de données dans un protocole de niveau supérieur.
- REQUEST-CERTIFICATE (envoyé en chiffré en phase 2) contenant les informations suivantes :
ð MSG-REQUEST-CERTIFICATE ;
ð AUTHENTICATION-TYPE ;
ð CERTIFICATE-CHALLENGE-DATA ;
Ce message peut être envoyé à tout instant par le serveur pendant la seconde phase du handshake. Le client répond immédiatement avec un message CLIENT-CERTIFICATE s’il en a un, ou avec un message d’erreur (avec le code NO-CERTIFICATE-ERROR) s’il n’en a pas.
Le protocole d’handshake SSL implémente un certain nombre de messages pouvant être envoyés par le serveur ou le client.
- ERROR (envoyés en clair ou chiffré)
ð MSG-ERROR ;
ð ERROR-CODE-MSB ;
ð ERROR-CODE-LSB ;
Ce message est envoyé quand une erreur est détectée. Une fois le message envoyé, la partie destinatrice enregistre l’erreur et arrête la connexion. Ce message est envoyé en clair si l’erreur arrive pendant la négociation des clés de session. Après entente sur les clés de session, les erreurs sont envoyées chiffrés comme tous les autres messages.
Les échanges SSL peuvent être résumés par le schéma ci-dessous :
Figure 50 : Le fonctionnement du protocole SSL
Différentes attaques du protocole SSL sont théoriquement possibles. Il n’existe pas à ce jour d’attaques connues ayant permis de casser le protocole SSL.
SSL dépend de plusieurs technologies cryptographiques différentes. Le chiffrement par clé publique de RSA ou par Diffie-Hellman est utilisé pour l’échange de la clé de session et pour l’authentification du client/serveur. Différents algorithmes cryptographiques sont utilisés. Si des attaques cryptographiques sont réalisées avec succès contre ces technologies, le protocole SSL ne pourra plus être considéré comme sûr.
Des attaques contre une session de communication spécifique peuvent être réalisées en enregistrant la session et ensuite utiliser cet enregistrement pour craquer soit la clé de session, soit la clé publique RSA jusqu’à l’obtention de la communication claire. Cette approche est plus facile que de casser les technologies cryptographiques pour tous les messages possibles. Il faut noter que le protocole SSL tente de rendre le coût d’une telle attaque supérieur au bénéfice d’une attaque réussie, l’attaque devenant donc une perte d’argent et/ou de temps.
Les attaques à “texte clair” ont lieu lorsque l’attaquant a une idée du message chiffré qui est envoyé. L’attaquant peut générer une base de données dont les clés sont la valeur cryptée du texte clair et dont les valeurs sont la clé chiffrée. Lorsque cette base de données est construite, une simple fonction de recherche identifie la clé de session qui va avec une valeur chiffrée particulière. Une fois la clé de session connue, le message entier peut être déchiffré.
A cause de la nature même de SSL, les attaques à “texte clair” sont possibles. SSL tente tout de même d’éviter ce genre d’attaque en utilisant des clés de session très grandes. En effet, le client génère une clé de grande taille et envoie une portion de celle-ci en clair au serveur. Cette portion claire de la clé, concaténée avec la portion secrète donne une clé très grande.
Chaque bit ajouté à la longueur de la clé double la grandeur de la base de données. En utilisant une clé d’une longueur de 128 bits, la base de données nécessaire n’est pas réalisable. Même si une base de données plus petite est utilisée, elle doit d’abord être générée avec les bits clairs. Il s’agit alors d’un processus très lent et coûteux.
Une conséquence de la défense SSL est que les attaques de force brute deviennent les attaques les moins chères. Les attaques de force brute ont un rapport espace/temps bien connu, et il devient alors possible de déterminer le coût d’une attaque. Il est important de noter que si pour une clé à 128 bits, le coût est théoriquement infini, ce coût est fortement réduit dans le cas de l’utilisation d’une clé à 40 bits.
Une attaque par rejeu est relativement simple à mettre en oeuvre. Une personne enregistre une session de communication entre un client et un serveur. Plus tard, cette personne se connecte à ce même serveur et rejoue les messages du client qu’il vient d’enregistrer.
Le protocole SSL élimine cette attaque en utilisant une « nonce » (connection-id) qui est « unique » pour chaque connexion. En théorie, l’attaquant ne peut prédire à l’avance la nonce utilisée car elle est basée sur une série d’événements sur lesquels il n’a aucun contrôle et ne peut donc pas répondre aux demandes du serveur.
Il est théoriquement envisageable d’enregistrer un grand nombre de sessions entre un client et un serveur et de tenter de choisir la bonne session en se basant sur la nonce que le serveur envoie initialement dans son message SERVER-HELLO. Il faut cependant noter que les longueurs des nonces SSL étant de 128 bits, un attaquant potentiel aura besoin de 264 nonces pour avoir 50% de chance de choisir la bonne session. Ce nombre est suffisamment grand pour rendre le coût du matériel nécessaire à l’enregistrement prohibitif.
L’attaque de “l’homme au milieu” peut avoir lieu lorsque trois personnes sont dans une session de communication : le client, le serveur et l’attaquant. Ce dernier se situe sur le réseau entre le client et le serveur et intercepte le trafic provenant à la fois du client et du serveur.
L’homme du milieu opère en faisant semblant d’être le vrai serveur envers le client. Avec SSL, cette attaque est impossible grâce à l’utilisation de certificats serveur. Durant la poignée de main initiale, le serveur doit présenter un certificat signé par une autorité. La clé publique du serveur, son nom ainsi que le nom du donneur du certificat sont contenus dans le certificat du serveur. Le client vérifie le certificat en regardant la signature et en vérifiant si le nom du donneur de certificat est une autorité reconnue par le client. Le serveur devant de plus chiffrer des données à l’aide de la clé privée associée à la clé publique mentionnée dans le certificat, seul un serveur possédant à la fois le certificat et la clé privée peut répondre convenablement à ce challenge.
Dans le cas d’une attaque de l’homme du milieu, la fourniture d’un faux certificat fera systématiquement échouer la phase de vérification. La fourniture d’un certificat valide ne suffira pas non plus à établir le canal SSL, l’homme du milieu ne possédant pas la clé privée associée.
La solidité des mécanismes SSL repose sur la solidité du certificat identifiant le serveur à atteindre. Il est à noter qu’un pirate peut facilement obtenir ou générer un certificat correspondant au serveur qu’il souhaite pirater. Il est à la charge de l’utilisateur de vérifier que le certificat du serveur qui a servi à établir la connexion SSL est bien le certificat correspondant au serveur réel et non un certificat falsifié. Faire reposer une implémentation SSL sur des certificats serveurs autosignés ne permet en aucune façon de garantir une réelle sécurité !!