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 avant que le protocole
d’application ne reçoive son premier byte d’information.
Voici la situation des couches dans le modèle OSI, qui
compte 7 couches.
L'IANA réserve les numéros de port suivants pour les
communications sécurisées par SSL:
- 443: réservé pour l'utilisation de Hypertext Transfer
Protocol avec SSL (https)
- 465: réservé pour l'utilisation de Simple Mail Transfer
Protocol avec SSL (ssmtp)
- 563: réservé pour l'utilisation de Network News Transfer
Protocol (snntp)
Un protocole d’application de ‘niveau supérieur’ peut 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 :
L’en-tête de la structure record définit une valeur appelée PADDING. La valeur du PADDING spécifie le nombre de bytes de données ajoutés à la structure originale par le destinateur. 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 cryptage.
Le destinataire de la structure décrypte 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.
MAC-DATA[MAC-SIZE]
ACTUAL-DATA[N]
PADDING-DATA[PADDING]
ACTUAL-DATA est la donnée actuelle transmise. PADDING-DATA est la donnée tampon envoyée quand un bloc clé est utilisé. MAC-DATA, finalement est le code d’authentification de message (Message Authentication Code).
Quand les structures SSL sont envoyées en clair, aucune clé n’est utilisée. Ainsi, la valeur du PADDING-DATA sera à zéro et la valeur de MAC-DATA aussi. Quand il y a chiffrement, ces valeurs changent selon certaines valeurs.
Le MAC-DATA est calculé de la manière suivante :
MAC-DATA = HASH[ SECRET, ACTUAL-DATA, PADDING-DATA, SEQUENCE-NUMBER
]
SEQUENCE-NUMBER est un compteur qui est incrémenté par
le client et le serveur. Chaque fois qu’un message est envoyé le
compteur est incrémenté. La valeur de SECRET dépend
de la partie qui envoie le message. Si le client envoie le message alors
SECRET est CLIENT-WRITE-KEY (le serveur utilisera SERVER-READ-KEY pour
vérifier le MAC). Si le client reçoit le message, alors SECRET
est CLIENT-READ-KEY (le serveur utilisera SERVER-WRITE-KEY pour générer
le MAC).
Nous avons donc:
SERVER-READ-KEY = CLIENT-WRITE-KEY
SERVER-WRITE-KEY = CLIENT-READ-KEY
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é endommagée et doit être traitée comme si une ‘erreur I/O’ était arrivée.
La couche SSL est utilisée pour toutes les communications SSL,
où sont inclus les messages de poignées de mains et les transferts
de données.
Quand une nouvelle clé est exigée, le message SERVER-HELLO contiendra assez d’information 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 cryptage).
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.
Quand un des partis a authentifié l’autre, il envoie son message
d’arrêt. Pour le client, par exemple, le message CLIENT-FINISHED
contient la forme encryptée de ‘connection-id’. Si la vérification
rate, le serveur envoie un message d’erreur. Une fois qu’une partie a envoyé
son message d’arrêt, il doit continuer à écouter les
messages du correspondant jusqu’à ce qu’il reçoive un message
d’arrêt. Dès qu’un parti a envoyé et reçu un
message d’arrêt, le protocole handshake SSL est fini. A ce moment-là,
le protocole d’application commence à s’exécuter.
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 lequel des deux partis 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 parti 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.
Quand un client se connecte au serveur, il envoie le message CLIENT-HELLO comme premier message. Le client envoie au serveur sa version SSL, sa clé de cryptage, 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. Après que le serveur et le client se soient mis d’accord sur une paire de clés, le serveur renvoie un message SERVER-VERIFY avec la forme cryptée de CHALLENGE-DATA.
A noter que le serveur n'enverra pas son message SERVER-HELLO avant
d'avoir reçu le message CLIENT-HELLO, cela pour permettre au serveur
d’indiquer dans son premier message l’état des sessions renvoyées
par le client (les performances du protocole sont ainsi augmentées
et on évite des tours pour rien)
char MSG-CLIENT-MASTER-KEY
char CIPHER-KIND[3]
char CLEAR-KEY-LENGTH-MSB
char CLEAR-KEY-LENGTH-LSB
char ENCRYPTED-KEY-LENGTH-MSB
char ENCRYPTED-KEY-LENGTH-LSB
char KEY-ARG-LENGTH-MSB
char KEY-ARG-LENGTH-LSB
char CLEAR-KEY-DATA[MSB<<8|LSB]
char ENCRYPTED-KEY-DATA[MSB<<8|LSB]
char KEY-ARG-DATA[MSB<<8|LSB]
Le client envoie ce message quand il a déterminé la clé
maître. Quand les deux partis se sont mis d’accord sur une session,
ce message n’est pas envoyé. Le champ CIPHER-KIND indique la clé
de chiffrement choisie à partir du CIPHER-SPECS du serveur. Le CLEAR-KEY-DATA
contient la portion en clair de MASTER-KEY. Le CLEAR-KEY-DATA est combiné
avec le SECRET-KEY-DATA pour former le MASTER-KEY. Le ENCRYPTED-KEY-DATA
contient les portions secrètes du MASTER-KEY, chiffrées en
utilisant la clé publique du serveur.
char MSG-CLIENT-CERTIFICATE
char CERTIFICATE-TYPE
char CERTIFICATE-LENGTH-MSB
char CERTIFICATE-LENGTH-LSB
char RESPONSE-LENGTH-MSB
char RESPONSE-LENGTH-LSB
char CERTIFICATE-DATA[MSB<<8|LSB]
char RESPONSE-DATA[MSB<<8|LSB]
Ce message est envoyé par un client en réponse au message REQUEST-CERTIFICATE du serveur. Le CERTIFICATE-DATA contient des données définies par la valeur du CERTIFICATE-TYPE. CERTIFICATE-TYPE est en général : SSL_X509_CERTIFICATE. Le CERTIFICATE-DATA contient un certificat X509 signé.
Un certificat X.509 contient les informations suivantes :
X.509-Certificate ::= SEQUENCE {
certificateInfo CertificateInfo,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING
}
CertificateInfo ::= SEQUENCE {
version [0] Version DEFAULT v1988,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo
}
Version ::= INTEGER { v1988(0) }
CertificateSerialNumber ::= INTEGER
Validity ::= SEQUENCE {
notBefore UTCTime,
notAfter UTCTime
}
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY ALGORITHM OPTIONAL
}
Le client envoie ce message quand il est satisfait avec le serveur.
N’oublions pas que le client doit continuer à écouter les
messages provenant du serveur jusqu’à ce qu’il reçoive le
message SERVER-FINISHED. La donnée CONNECTION-ID est l’identification
originale de la session que le serveur envoie dans le message SERVER-HELLO.
‘N’ est le nombre de bytes du message envoyé.
char MSG-SERVER-HELLO
char SESSION-ID-HIT
char CERTIFICATE-TYPE
char SERVER-VERSION-MSB
char SERVER-VERSION-LSB
char CERTIFICATE-LENGTH-MSB
char CERTIFICATE-LENGTH-LSB
char CIPHER-SPECS-LENGTH-MSB
char CIPHER-SPECS-LENGTH-LSB
char CONNECTION-ID-LENGTH-MSB
char CONNECTION-ID-LENGTH-LSB
char CERTIFICATE-DATA[MSB<<8|LSB]
char CIPHER-SPECS-DATA[MSB<<8|LSB]
char CONNECTION-ID-DATA[MSB<<8|LSB]
Le serveur envoie ce message après avoir reçu le message CLIENT-HELLO du client. Le serveur renvoie SESSION-ID-HIT indiquant si oui ou non, l’identification de la session est connue par le serveur. Quand la valeur de SESSION-ID-HIT est zéro, le serveur regroupe son certificat, ses paramètres algorithmiques et une identification de connexion pour l’envoyer au client. Ce client, en utilisant cette information, pourra générer une clé de session et la renvoyer au serveur avec le message CLIENT-MASTER-KEY.
Quand SESSION-ID-HIT est non nul, 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 MASTER-KEY qui fut échangé quand la SESSION-ID fut créée.
Le message SERVER-HELLO est envoyé après que le serveur
ait reçu le message CLIENT-HELLO, et avant que le serveur envoie
le message SERVER-VERIFY.
char MSG-SERVER-VERIFY
char CHALLENGE-DATA[N-1]
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 avec 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 pair de clés de session (SERVER-READ-KEY et SERVER-WRITE-KEY).
Finalement, seul un serveur qui a fait l’extraction et le décryptage
proprement peut correctement crypté CHALLENGE-DATA. Cela prouve
donc que le serveur a la clé privée qui va avec la clé
publique contenue dans le certificat du serveur.
Le serveur envoie ce message quand il est satisfait de la sécurité
du handshake du client et qu’il est prêt à procéder
à une transmission/réception de données dans un protocole
de niveau supérieur. Le SESSION-ID-DATA est 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.
char MSG-REQUEST-CERTIFICATE
char AUTHENTICATION-TYPE
char CERTIFICATE-CHALLENGE-DATA[N-2]
Un serveur peut à tout instant faire cette demande 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.
char MSG-ERROR
char ERROR-CODE-MSB
char ERROR-CODE-LSB
Ce message est envoyé quand une erreur est détectée. Après que le message soit envoyé, la partie destinateur arrête la connexion. Le destinataire enregistre l’erreur et arrête ensuite la connexion.
Ce message est envoyé en clair si l’erreur arrive pendant
la négociation des clés de session. Après qu’il ait
eu entente sur les clés de session, les erreurs sont envoyées
cryptés comme tous les autres messages.
client-hello
C -> S: challenge, cipher_specs
server-hello
S -> C: connection-id,server_certificate,cipher_specs
client-master-key C -> S:
{master_key}server_public_key
client-finish
C -> S: {connection-id}client_write_key
server-verify
S ->; C:{challenge}server_write_key
server-finish
S -> C: {new_session_id}server_write_key
Le client envoie le message CLIENT-HELLO où se trouvent les différents
paramètres du cryptage (cipher_specs) et les données challenge.
Le serveur renvoie le SERVER-HELLO. On y trouve le certificat du serveur,
une numéro d’identification de connexion et les paramètres
de chiffrement. Une clé maître a du être créée
puisqu’aucune session est authentifiée. La poignée de mains
se termine lorsque chacun des partis envoie leur message finish.
client-hello
C -> S: challenge, session_id, cipher_specs
server-hello S -> C:
connection-id, session_id_hit
client-finish
C -> S: {connection-id}client_write_key
server-verify S -> C: {challenge}server_write_key
server-finish S ->
C: {session_id}server_write_key
Ici, aucune clé maître n’est créée et l’on
utilise les clés secrètes de la session authentifiée.
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. Cet approche est plus facile que de craquer les
technologies cryptographiques pour tous les messages possibles. Notez que
SSL tente de rendre le coût d’une telle attaque supérieur
au bénéfice d’une attaque réussie, l’attaque devient
donc une perte d’argent et/ou de temps.
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. D’abord, le client génère une clé plus grande que permise par exportation, 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.
Le hardware nécessaire pour réaliser une telle attaque est donc rendue prohibitive. 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. Pour une clé
à 128 bits, le coût est théoriquement infini. Pour
une clé à 40 bits, ce coût est fortement réduit
mais toujours hors de portée d’un “random hacker”.
SSL élimine cette attaque en utilisant une “nonce” (connection-id) qui est “unique” pour chaque connexion. En théorie, le malfrat ne peut prédire à l’avance la nonce car elle est basée sur une série d’événements sur lesquels il n’a aucun contrôle. Le malfrat ne peut donc pas répondre aux demandes du serveur.
Une personne avec un bon matériel peut enregistrer beaucoup de session entre un client et un serveur et tenter de choisir la bonne session en se basant sur la nonce que le serveur envoie initialement dans son message SERVER-HELLO. Cependant, les nonces SSL ont une longueur de 128 bits. Le malfrat aurait donc besoin d’environ 264 nonces pour avoir 50% de chance de choisir la bonne session. Ce nombre est suffisamment grand que pour rendre le coût du matériel nécessaire à l’enregistrement prohibitif.
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 du serveur. Durant la poignée de main initiale, le serveur est demandé à 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 quelqu’un que le client reconnaît.
De plus, le serveur doit chiffrer quelque chose avec la clé privée qui s’associe avec la clé publique mentionnée dans le certificat. Seul un serveur qui possède à la fois le certificat et la clé privée peut répondre convenablement à ce challenge.
Si l’homme du milieu fournit un faux certificat, la vérification de la signature le détectera. Si la signature est une signature légitime pour le malfrat mais pas pour le serveur, la signature passera mais alors c’est la vérification du nom du serveur qui détectera l’effraction.
Finalement, si le malfrat fournit un certificat légitime pour le serveur en question, la signature et le nom passeront. Cependant, le malfrat, ne possédant pas la clé privée du serveur, ne pourra pas encoder convenablement sa réponse au challenge et sera détecté lors de cette dernière vérification.
Dans le cas très peu probable où le malfrat a deviné
la clé privée, il ne peut toujours pas déchiffrée
la clé de session et ne peut donc pas visualiser l’information chiffrée.
A tout seigneur, tout honneur. Voici donc la page de Netscape traitant de SSL . SSL n'est pas le seul résultat de recherche de sécurité sur internet. Pour vous en convaincre, visitez cette page.
SSL étant un standard de fait, l'IETF s'en inspire largement pour établir un draft: TLS (transport layer security).
Voici deux sites traitant des certificats X.509: Public key infrastructure , X.509 certificate. Ces certificats sont délivrés par des autorités de certification. Si la plus connue est Verisign, tout le monde ne connaît pas Belsign, société belge, pionnière européenne en la matière, et reconnue par Netscape et Microsoft..
RSA Data Security n'est pas la seule société présente dans le domaine du chiffrement. Un de ses challengers est Certicom.
Voici enfin le site de Dell qui vend des PC en ligne, les échanges
de données étant sécurisées par SSL. Pour ceux
qui ne croient pas encore que le commerce électronique est un grand
enjeux, voici e-Christmas, site
dédié à la promotion du commerce électronique
en Europe. Parmi ses instigateurs, on retrouve Hewlet
Packard et Microsoft.
L'utilisation de la cryptographie sur internet mène parfois
à des situation cocasses.
Ainsi, les Etats-Unis considèrent la cryptographie à 128 bits comme une arme, et interdisent donc son exportation. C'est ainsi que la version de PGP disponible pour les européens est une version bridée. Mais le plus surprenant dans cette histoire est que ces mêmes Etats-Unis sont pour la libre circulation des livres. Ceci a donnée l'idée à quelqu'un de transcrire l'algorithme de PGP dans un livre, de l'envoyer en Europe où il a été réencodé. PGP était disponible en Europe!
La France quant à elle a une législation aussi sévère
que celle de l'Iran en la matière (crypto uniquement autorisée
pour les transactions banquaires, dépôt des clef à
une autorité,...). Si vous vous rendez sur le site FTP
de Netscape, vous verrez qu'une version spécialement destinée
à la France se trouve dans le répertoire /pub/communicator_for_france
!