Authentification client serveur
Un article de Le wiki de 2 noisettes - noisette.ch.
Sommaire |
Introduction
Le problème de l'authentification d'un client auprès d'un serveur peut être facilement résolu par des primitives cryptographiques comme les paires de clés publiques/privées (PK), les clés symmétriques de sessions et les protocoles challenge/response. Le problème inverse, l'authentification du serveur auprès du client, est lui aussi très bien résolu avec les certificats et les signatures des autorités de certifications (CA).
Néamoins, dans les applications légères où on ne veut déployer ni une CA ni une PKI (infrastructure de gestion des PK), le problème reste complexe à traiter.
On a observé récemment une augmentation des virus et vers qui modifient les fichiers hosts (/etc/hosts ou c:\windows\system32\drivers\etc\hosts) afin de pouvoir tromper l'utilisateur et l'envoyer vers une copie du site qu'il pensait atteindre.
Client peu sûr
L'hypothèse qui prévaut dans cet exemple est donc que toutes les informations stockées chez le client peuvent être modifiées. On part ainsi du principe que la copie locale du certificat serveur, utilisé par le client pour authentifier sûrement le serveur qu'il contacte, peut être modifiée et donc ne pas émettre d'avertissement en cas de contact d'un faux serveur.
L'idée est donc de spécifier un protocole d'authentification mutuelle forte entre un client et un serveur : le client sera sûr de parler au bon serveur, et le serveur aura authentifier le client, le tout avec un seul secret commun : le mot de passe du client.
Les méthodes cryptographiques utilisées resteront des fonctions classiques comme SSL, AES, ..., car elles sont éprouvées.
Prérequis
Le serveur dispose d'un certificat permettant l'étblissement d'une connexion sécurisée avec un client (SSL par exemple). Il disposera en outre une paire nom d'utilisateur/hash du mot de passe du client, auparavant établi et échangé de manière sûr.
Protocole
Une fois une connexion sécurisée quelconque (SSL) établie entre le client et le serveur, le protocole d'authentification mutuelle commence :
|
Note : la première version du protocole, où le serveur envoyait son certificat crypté au client, était vulnérable à une replay attack : une personne mal attentionnée qui sniffait le réseau pouvait, lors de la prochaine authentification du client, émuler le serveur en envoyant le certificat encrypté entendu sur le réseau. Le client n'aurait rien vu et aurait envoyé son hash au faux serveur.
Conclusion
Ce protocole d'authentification mutuelle est très pratique dans les cas où une infrastructure légère est requise. Néamoins, la base client du serveur ne doit à aucun moment être compromise. Faute de quoi un autre serveur pourra prendre ce rôle.
Note : ce schéma n'est pas résistant à une attaque de type "man-in-the-middle", type d'attaque impossible à parer sans avoir de secret partagés. Un autre problème rencontré (duquel découle l'attaque précédente en fait) et l'information leakage dont est victime le client qui révèle son nom d'utilisateur. A corriger donc.
Pour la correction, une première idée serait d'inverser les roles d'identification (donc 1 : le serveur, 2 : le client) et d'envoyer un token contenant le nom du client hashé avec le challenge, mais le serveur devrait tester la correspondance avec tous les clients de la base pour retrouver la correspondance, ce qui est peu performant si la base contient beaucoup de clients.


