cryptosec

SSL-TLS

Sécurisation de flux applicatifs

Généralités :

SSL (Secure Socket Layer) est un protocole à négociation (on parle du " handshake " SSL), développé à l’origine par Netscape.
Il a pour but de sécuriser les transactions Internet, par authentification du client (un navigateur la plupart du temps) et du serveur, et par chiffrement de la session.

La sécurisation des connexions à l’aide du protocole SSL doit assurer que :
- La connexion assure la confidentialité des données transmises
- La connexion assure que les données transmises sont intègres
- L’identité des correspondants peut être authentifiée
- La connexion est fiable

La version 2.0 vient de Netscape et la version 3.0, qui est actuellement la plus répandue, à reçu les contributions de la communauté internationale.

TLS (Transport Layer Security protocol), développé par l’IETF, est la version 3.1 de SSL.

SSL ne dépend pas des applications utilisées lors des transactions et s’applique sous les protocoles HTTP, FTP, Telnet... etc.
Clients et serveurs commencent par s’authentifier mutuellement, puis négocient une clé symétrique de session qui servira à assurer la confidentialité des transactions. L’intégrité de ces dernières est assurée par l’application de HMAC (Hashed Message Authentification Code).

Principe :

Les clés asymétriques utilisées lors des transactions SSL sont encapsulées dans des certificats X.509 version 3, générés par bon nombre d’autorités de certification ou de PKI.

On distingue deux phases lors du déroulement du handshake SSL :

Authentification du serveur et authentification optionnelle du client.

Première phase :

Suite à la requête d’un client, le serveur envoie au client son certificat et lui liste les algorithmes qu’il souhaite utiliser. Le client vérifie la validité du certificat (à l’aide delà clé publique de l’AC contenue dans son navigateur, des dates de validité et, éventuellement, en consultant une CRL (rarement dans la pratique)), puis, si le certificat est valide, génère une clé maître (symétrique), la chiffre à l’aide de la clé publique du serveur et la lui envoie. Les données échangées par la suite entre le client et le serveur sont chiffrées et authentifiées à l’aide de clés dérivées de la clé maître.

Deuxième phase, optionnelle (et souvent non utilisée) :

Le serveur envoie au client un challenge (une petite série de bits) que le client doit signer, à l’aide de sa clé privée correspondant à son certificat, et le renvoyer au serveur pour s’authentifier. Il lui envoie de même son certificat, que le serveur vérifiera avant de poursuivre les transactions.

Les détails du protocole SSL :

Une session SSL est définie par les paramètres suivants partagés entre un client et un serveur :

Session identifier : un octet fixé par le serveur pour identifier la session
Peer certificat : un certificat pour le serveur, éventuellement un autre pour le client
Cipher Spec : définit l’algorithme de chiffrement symétrique et l’algorithme de condensation
Master secret : clé de 48 octets négociée entre le serveur et le client
Compression method : NULL pour l’instant (en SSLv3 ou TLS)
Is resumable : flag qui indique si de nouvelles connexions peuvent être créées à partir de cette session

Une connexion SSL est définie par les paramètres suivants partagés entre un client et un serveur :

Server and client random : des octets aléatoires déterminés par le client et le serveur pour chaque connexion
Server write (send) MAC secret : clé secrète utilisée par le serveur pour faire les MAC
Client write (send) MAC secret : clé secrète utilisée par le client pour faire les MAC
Server write (send) key : clé symétrique utilisée par le serveur pour chiffrer les données
Client write (send) key : clé symétrique utilisée par le client pour chiffrer les données
Initialization vectors : pour un algorithme de chiffrement par bloc en mode CBC. Le premier est fixé lors du handshake, les suivants sont les derniers blocs des précédents fragments chiffrés
Sequence number : chaque message est numéroté de part et d’autre



Le protocole SSL est constitué des sous-protocoles :

Le protocole SSL handshake
Le protocole SSL Change Cipher Spec (voir la fin du Handshake... c’est le plus court protocole que j’ai rencontré jusqu’à présent... 1 octet !)
Le protocole SSL Alert
Le protocole SSL Record

Le protocole SSL handshake
Ce protocole permet au client et au serveur de s’authentifier mutuellement, de négocier les algorithmes de chiffrement, de négocier les algorithmes de MAC et enfin de négocier les clés symétriques qui vont servir au chiffrement.

Chaque message échangé entre le client et le serveur contient trois champs :
Type, indique l’objet du message (1 octet)
Lenght, indique la longueur du message (3 octets)
Content, contient les données transmises (plus d’un octet)


Phase 1 : Etablissement des paramètres de sécurité
Cette phase à pour but d’établir le lien sécurisé. Les paramètres du premier message, client_hello, envoyé par le client, sont :

Version : la plus haute version de SSL que puisse utiliser le client.

Random : un horodatage de 32 bits et une valeur aléatoire de 28 octets générée par le client. Ces valeurs servent de sel et sont utilisées pour se prémunir contre les rejeux de paquets.

Session ID : Un nombre, qui identifie la connexion. Un zéro signifie la volonté du client d’établir une nouvelle connexion sur une nouvelle session. Un autre nombre signifie la volonté de changer les paramètres ou de créer une nouvelle connexion sur la session existante.

CipherSuite : Une liste, par ordre décroissant de préférence, des algorithmes que supporte le client. Il s’agit des algorithmes d’échange de clé et de chiffrement.

Key Exchange :

RSA (clé symétrique chiffrée avec clé RSA contenue dans un certificat)
Diffie-Hellman (si le certificat serveur contient des paramètres D-H (Diffie-Hellman). Le client n’est pas obligé de présenter un certificat si l’authentification du client n’est pas demandée par le serveur)
Diffie-Hellman temporaire (Une clé symétrique D-H est négociée, les transactions étant signées par des clés RSA ou DSS certifiées par une AC. C’est la plus sûre des méthodes parce que la clé générée est unique et authentifiée)
Diffie-Hellman anonyme (Un simple échange D-H est effectué, sans authentification des partenaires. Vulnérable à "l’attaque du milieu")
Fortezza

CipherSpec :

Cipher Algorithm : DES-40 ; DES, 3-DES, RC2, RC4, IDEA, Fortezza
MACAlgorithm : MD5 ou SHA-1
CipherType : Stream ou Block
IsExportable : True ou False
HashSize : 0, 16 (MD5) ou 20 octets (SHA-1)
Key Material : des octets contenant une partie des données utilisées pour générer les clés.
IV Size : Taille des Vecteurs d’Initialisation pour le chiffrement en mode CBC.

Compression Method : liste, par ordre décroissant de préférence, des algorithmes de compression supportés par le client.

Après avoir envoyé ces requêtes, le client attend que le serveur réponde en générant une valeur aléatoire, en indiquant la version, et les meilleurs algorithmes qu’il peut utiliser : ce sera la réponse server_hello du serveur.

Phase 2 : Authentification du serveur et échange des clés

Lors de cette phase, le serveur commence par envoyer son certificat. Ce message peut contenir une chaîne de certificats X.509. L’échange de clés entre serveur et client n’est possible sans que le serveur n’envoie son certificat que dans le cas d’un Diffie-Hellman anonyme ; dans tous les autres cas, le serveur présente son certificat.
Le serveur envoie un message server_key_exchange si le client et le serveur veulent utiliser du D-H anonyme (un nombre premier, un nombre qui lui est relativement premier et la clé publique D-H du serveur), du D-H temporaire (les paramètres D-H et une signature), du RSA key exchange (ou le serveur n’a qu’une clé RSA pour signer et veut établir une clé RSA temporaire) ou Fortezza. Les signatures sont effectuées en utilisant les fonctions de condensation, comprennent les sels initiaux et sont chiffrées grâce aux clés privées (ceci assure que le serveur détient la clé privée associée à la clé publique que contient le certificat).
Ensuite, le serveur peut demander au client un certificat : c’est le message certificate_request (rarement implémenté dans la réalité), qui comprend les champs certificate_type (algorithme public utilisé) et certificate_authorities (liste des AC valides).
Finalement, le serveur envoie le message server_done, qui signifie la fin de cette phase et que le serveur se met en attente.

Phase 3 : Authentification du client et échange des clés

Le client doit vérifier que le certificat envoyé par le serveur est valide (c’est souvent là que le système est bancal), et que les autres paramètres sont corrects. Si le serveur à demandé au client d’envoyer un certificat, le client envoie un message certificate, contenant le certificat (s’il n’a pas de certificat, il envoie un message no_certificate).
Le client envoie ensuite un message client_key_exchange, qui dépend de l’algorithme choisi :

RSA : le client génère une clé secrète de 48 octets qui servira à générer la définitive, et la chiffre avec la clé publique du serveur.
D-H anonyme ou temporaire : ce sont les paramètres D-H du client qui sont envoyés.
Diffie-Hellman : Dans ce cas les paramètres D-H ont été envoyés avec le certificat, et ce message est donc vide
Fortezza : les paramètres Fortezza...

Pour finir cette phase, le client envoie un message certificate_verify (sauf si le certificat ne contient que des paramètres D-H, i.e. certificat qui ne peut servir à signer). Ce message consiste en un condensât des messages échangés pendant le handshake, de la clé symétrique générée et des pad, le tout signé avec la clé privée du client. Le but de ce message est de s’assurer que le client est bien en possession de la clé privée correspondant à la clé publique envoyée dans le certificat (c’est bien beau de présenter un certificat... si on ne prouve pas que l’on possède la clé privée correspondante).

Phase 4 : Fin

Le client envoie le message (1 octet) change_cypher_spec, qui est en fait l’unique message du protocole Change Cipher Spec, et active pour la session courante les algorithmes, clés et sels du handshake. Puis le client envoie le message finished, qui authentifie le client et valide l’échange de clé (le message est constitué d’un condensât de la clé symétrique échangée, de l’ensemble des messages échangées durant le handshake, du pad et d’un identificateur de l’expéditeur).
Le serveur répond en envoyant son propre change_cypher_spec et clos le handshake.

Le protocole SSL Alert

Ce protocole spécifie les messages d’erreur que peuvent s’envoyer clients et serveurs. Les messages sont composés de deux octets, le premier est soit "warning" soit "fatal". Si le niveau est "fatal", la connexion est abandonnée. Les autres connexions sur la même session ne sont pas coupées mais on ne peut pas en établir de nouvelles.
Le deuxième octet donne le code d’erreur.

Les erreurs fatales sont :
unexpected_message : message non reconnu
bad_record_mac : MAC non correct
decompression_failure : la fonction de décompression à reçu une mauvaise entrée
handshake_failure : impossible de négocier les bons paramètres
illegal_parameter : un champ était mal formaté ou ne correspondait à rien

Les warnings sont :
close_notify : annonce la fin d’une connexion
no_certificate : réponse à une demande de certificat s’il n’y en a pas.
bad_certificate : le certificat reçu n’est pas bon (e.g. signature non valide)
unsupported_certificate : le certificat reçu n’est pas reconnu... vive la compatibilité !)
certificate_revoked : cert révoqué par l’émetteur
certificate_expired : ...
certificate_unknown : tous les problèmes concernant les certificats et non listés au dessus...

Le protocole SSL Record

Ce protocole permet de garantir :

La confidentialité des données transmises (c’est le Handshake qui permet de négocier une clé symétrique partagée)
L’intégrité des données transmises (c’est encore le Handshake qui négocie une clé partagée qui sert à faire des MAC sur les données)

Schématiquement, le protocole SSL Record ressemble à :


Dans l’entête qui est ajoutée :

Content Type : le plus haut protocole utilisé pour traiter ce fragment
Major Version : plus haute version de SSL utilisée (3 pour SSLv3)
Minor Version : plus basse version utilisée (0 pour SSLv3)
Compressed Lenght : la longueur en octets des données (éventuellement compressées) à chiffrer.

Le MAC est fait de la façon suivante (effectué avant chiffrement, puis chiffré) :

HASH(clé partagée||pad_2||HASH(clé partagée||pad_1||numéro de ce massage||protocole pour ce message||longueur de ce message||les données (compressées))

La fonction de condensation (HASH()) est soit MD5 soit SHA-1

pad_1 = 0x36 et pad_2 = 0x5C (répétés 40 fois pour SHA-1 et 48 fois pour MD5)

Les algorithmes autorisés sont :

3-DES 168
IDEA 128
RC4 128
Fortezza 80
DES 56
DES-40
RC4-40
RC2-40


Pour résumer, les protocoles s’assemblent de la facon suivante :


La pratique :

Pour accéder aux services SSL d’un serveur on ajoute habituellement un "s" lors de la spécification du protocole.
Exemple : https://www.monsite.org

Le trafic SSL ne s’accommode pas de l’utilisation de serveurs proxy classiques (cache et réplication) parce que SSL à été conçu pour contrer les attaques dites "de l’homme interposé", et que le proxy va être considéré comme un attaquant. Pour qu’un serveur proxy puisse gérer du trafic SSL, il doit supporter le protocole SOCKS (qui travaille au niveau socket) ou un protocole spécial de tunneling SSL. Netscape Proxy Server par exemple supporte les deux.

Liste des numéros de port associés à SSL :

Protocole Port TCP Description
nsiiops261IIOP Name Service sur TLS/SSL
https443http sur TLS/SSL
ddm-ssl448DDM-SSL
smtps465smtp sur TLS/SSL
nntps563nntp sur TLS/SSL
sshell614SSLshell
ldaps636ldap sur TLS/SSL
ftps-data989ftp données sur TLS/SSL
ftps990ftp controle sur TLS/SSL
telnets992telnet sur TLS/SSL
imaps993imap4 sur TLS/SSL
ircs994irc sur TLS/SSL
pop3s995pop3 sur TLS/SSL

Plutôt que des MAC, SSL utilise de HMAC, ou l’on ajoute la clé secrète au données avant de les hacher :

HASH(K,pad2,HASH(K,pad1,text))
Cela rend le hash beaucoup plus sûr.
pad1 et pad2 sont arbitraires (0x36 et 0x5C).

SSL v3 comporte dans la dernière transaction du handshake un condensât de tous les précédentes transactions (cela prémunit de l’attaque de l’homme interposé, qui peut par exemple forcer client et serveur à
adopter du 40 bits SSLv2, niveau de chiffrement nettement insuffisant aujourd’hui).

SSL est un protocole de sécurisation des transactions, pas des données enregistrées. Les données obtenues par SSL
enregistrées sur un disque local ne sont donc plus chiffrées.

Lors de l’établissement d’une connexion sécurisée SSL, beaucoup de clients SSL, comme Netscape Navigator, vérifient si le "CommonName" indiquant l’identité du site sur le certificat utilisé correspond au nom du site ; s’ils ne correspondent pas, l’application cliente avertit l’utilisateur. Le mieux est donc de donner comme CommonName aux serveurs web leur nom DNS (www.exemple.fr)
Mais toutes les AC n’acceptent pas ce genre de norme.

Il existe une implémentation OpenSource, et d’excellente qualité, de SSL v2.0, v3.0 et TLS 1.0, c’est SSLeay devenue OpenSSL.
La qualité de cette API en fait une des plus utilisée, notamment en conjonction avec Apache. Elle peut dans bien des cas remplacer avantageusement d’autres API (ou spécifications d’API comme GSS par exemple) pour sécuriser divers types de protocoles.

Les problèmes de SSL :

Problèmes liés au client SSL : le navigateur.

Les navigateurs n’ont pas (encore) de fonctionnalités évoluées
de gestion des clés :

Les certificats ne peuvent par exemple pas être automatiquement renouvelés et l’historique des clés n’est pas conservé. Quand un certificat expire, l’utilisateur reçoit un message et doit obtenir manuellement un nouveau certificat, ce qui n’est pas forcément trivial pour un utilisateur lambda. Ces problèmes seront probablement résolus lorsque les navigateurs deviendront des clients de PKI à part entière ;-)

La cryptographie utilisée par les navigateurs peut être soumise à des restrictions d’exportation (hors des Etats-Unis par exemple pour Netscape et Microsoft) cela force les utilisateurs à utiliser des clés de longueur insuffisante. Dans le cas de Netscape, on peut renforcer la crypto chez www.fortify.com par exemple... tout en veillant à rester en conformité avec la législation... (on peut aussi y voir quel est la crypto utilisée par son navigateur)

La relation de confiance est définie par la liste préinstallée des autorités de certification :
Les navigateurs du commerce sont livrés avec de nombreuses clés publiques pré-installées (Netscape en contient 33). Celles-ci sont utilisées pour la vérification de la signature de l’autorité de certification pour les certificats d’autres navigateurs ou serveurs. Pour être confirmé, un certificat doit être signé par n’importe laquelle des AC présentes dans le navigateur. Par conséquent, si l’une quelconque parmi les autorités de certification certifie un site frauduleux, ce certificat sera vérifié correctement par des millions de navigateurs. En tant qu’utilisateur, il est important d’aller voir dans les propriétés "sécurité" de son navigateur et de valider la confiance que l’on attribue aux diverses autorités de certification. Par défaut, les navigateurs font confiance à toutes...

Les mots de passe :
Sur MSIE (jusqu’a la version 5.0) le mot de passe protégeant les certificats est optionnel (comme beaucoup de choses... :) alors que protéger sa clé privée est vital.

Problèmes intrinsèques au protocole :

Le système est fondé sur une seule paire de clés :
Le principal problème que cela pose vient de la différence entre les contraintes qui pèsent sur le clés de signature/authentification et celles de chiffrement.
Avoir la possibilité de sauvegarder en central les clés de chiffrement peut s’avérer très pratique (si un utilisateur oublie son mot de passe il n’est par exemple pas nécessaire de régénérer une paire de clé et de la certifier à nouveau, mais on peut simplement lui renvoyer ses clés, en l’obligeant à ressaisir un mot de passe). Si les services d’un tiers sont utilisés pour la sauvegarde d’une unique paire de clé (service offert par certaines autorités de certification ou Tiers de Confiance), le client ne sera plus le seul à avoir accès à sa clé privée de signature et la non-répudiation n’est alors plus assurée.
Certes, gérer deux paires de clés est plus lourd que d’en gérer une seule.
La sauvegarde des clés est importante là où celles-ci sont utilisées pour chiffrer des données stockées, comme des courriers électroniques par exemple. Si les clés ne sont pas sauvegardées et que l’accès aux clés est perdu, les données chiffrées n’ont plus aucune utilité (et si en essayant d’en briser la protection on les récupère quand même, c’est alors l’application crypto qui n’est d’aucune utilité...).
Ce défaut est un peu théorique parce que SSL, dans la pratique, ne chiffre que des flux. Pour un utilisateur "isolé", il est au contraire souhaitable qu’aucune de ses clés privées ne soit ailleurs qu’en sa possession. Mais il est probable que dans l’avenir un même certificat servira à plusieurs types d’opérations cryptographiques, auquel cas ce problème se posera.

Le protocole SSL ne prévoit pas de vérification systématique des CRL :
Lorsqu’un serveur Web présente un certificat, le navigateur en vérifie sa validité ; cela consiste pour lui à :

Vérifier que les dates de validité sont valides
Vérifier que la signature appliquée au certificat est valide

Mais le protocole SSL n’impose pas qu’un certificat ne soit utilisé que suite à la consultation de la CRL qui lui correspond. Un serveur Web peut donc présenter aux navigateurs un certificat révoqué. Netscape 6 permet de vérifier automatiquement les CRL, grâce au protocole OCSP (Online Certificate Status Protocol, désactivé par défaut...) La vérification manuelle des CRL est laborieuse et quasiment jamais faite.

Attaques possibles contre SSL

On peut imaginer de construire un site très similaire à un site que l’on souhaite abuser. Il est ensuite possible d’acheter un certificat chez l’une des autorités de certification reconnues par les navigateurs. Le site est mis en place en utilisant un DN similaire (par exemple " www.monsite.org " au lieu de " www.monsite.com "), voir même en trompant un serveur DNS pour créer un duplicata de " www.monsite.com ". Les utilisateurs ne verront aucune différence, ils croiront être sur le site valide puisque son certificat est vérifié avec succès par le navigateur, et ceci même si le site réel utilise un certificat valide. Vu l’absence de consultation automatique des CRL par les navigateurs, l’autorité de certification qui à émis le certificat pour le site contrefait peut même ensuite révoquer ce certificat sans que les utilisateurs cessent d’en vérifier la validité.

Sources :

SSL version 3 :

http://home.netscape.com/eng/ssl3/index.html

TLS :

http://www.ietf.org/html.charters/tls-charter.html

HMAC :

http://andrew2.andrew.cmu.edu/rfc/rfc2104.html

SSLeay :

http://www.psy.uq.oz.au/ ftp/Crypto

OpenSSL :

http://www.openssl.org

OpenSSL et Apache :

http://www.apache-ssl.org


 
cryptosec
3 avril 2002

 
 
 
 
 
Partager sur Twitter  |  Partager sur LinkedIn
 

Afficher les commentairesMasquer les commentaires


 
modération a priori

Ce forum est modéré a priori : votre contribution n’apparaîtra qu’après avoir été validée par un administrateur du site.

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Creative Commons - BY - NC - ND

Tous les textes, images et sons de cryptosec sont publiés selon les termes de la licence Creative Commons - Attribution - Pas d’Utilisation Commerciale - Pas de Modification - 3.0