Parce que les données au repos sont vulnérables :
- certaines la base de données peuvent être récupérées par des failles stupides, comme les injections de code (aucun système ne doit pouvoir être vulnérable à ça; si vous pouvez être vulnérable, c'est que vous vous y prenez mal)
- certains protègent bien les serveurs, mais laissent traîner des sauvegardes en clair un peu partout
etc.
donc il est bon ne pas conserver trop de données en mémoire de masse sur le serveur : il serait souhaitable que si un adversaire récupère une copie de la base de données des utilisateurs :
1) il ne prenne pas connaissance des mots de passe en clair : pour ça, il ne faut donc pas que la base contienne les mots de passe en clair ou chiffrés d'une façon que le serveur sait déchiffrer;
2) il ne puisse pas usurper l'identité d'un utilisateur : pour ça, il faut donc que la base ne contienne pas les données qui permettent de s'authentifier auprès du serveur
1) Pour cela, on utilise une fonction "one way" (non inversible), c'est à dire un hachage cryptographique; on peut par exemple remplacer partout pw par hpw = hash(login || pw)
Le serveur ne stocke pour chaque utilisateur que hpw; ainsi le serveur ne peut pas récupérer les valeurs de pw à partir de la base de données. Lors d'une tentative d'authentification, il génère sid et peut calculer hash(hpw || sid) et le comparer à la valeur envoyée par le client.
2) Pour cela, on utilise aussi une fonction "one way" : le serveur demande un authentificateur, il applique une fonction non inversible et compare à une valeur connue :
Le serveur stocke hpw = hash(login || pw) pour chaque utilisateur.
Le protocole est simplement :
C->S : login,pw
Le serveur recalcule hash(login || pw) et compare à la valeur hpw stockée.
1) Dans ce cas, le serveur connaissant hpw peut usurper l'identité de n'importe quel utilisateur.
2) Dans ce cas, le serveur ne connaissant pas l'authenficateur pw, ne peut pas usurper l'identité d'un utilisateur.
On peut bien sûr combiner un peu les deux approches :
3) On évite de manipuler/stocker/transmettre pw, on utilise à place : hpw = hash(login || pw)
Le code secret est donc hpw et non pw.
On évite de transmettre hpw : on transmet l'authentificateur auth = hash(hpw); le serveur stocke hpw.
C->S : login,auth
Le serveur peut vérifier que auth = hash(hpw)
Donc
- le serveur ne dispose pas du mot de passe en clair (mais il dispose de hpw en clair)
- hpw n'est jamais transmis
- mais la propriété 2) n'est pas garantie : le serveur a l'info pour usurper n'importe quelle identité.