web-dev-qa-db-fra.com

Sécurité https - le mot de passe doit-il être haché côté serveur ou côté client?

Je crée une application Web qui nécessite que les utilisateurs se connectent. Toutes les communications passent par https. J'utilise bcrypt pour hacher les mots de passe.

Je suis confronté à un dilemme - je pensais qu'il était plus sûr de créer un hachage de mot de passe côté client (en utilisant JavaScript), puis de le comparer avec le hachage côté serveur DB. Mais je ne suis pas sûr que ce soit mieux que d'envoyer un mot de passe en texte brut sur https, puis de le hacher côté serveur.

Mon raisonnement est que si un attaquant peut intercepter le trafic https (= lire le mot de passe en texte brut), il peut par exemple également modifier le JavaScript afin qu'il envoie le mot de passe en texte clair à côté du mot de passe haché - où il peut l'intercepter.

La raison contre le hachage côté client est simplement la facilité d'utilisation. Si je hache côté client, je dois utiliser deux bibliothèques distinctes pour le hachage. Ce n'est pas un problème insurmontable, mais c'est une nuisance.

Y a-t-il un gain de sécurité à utiliser le hachage côté client? Pourquoi?

Dois-je également utiliser le challenge-response?

MISE À JOUR: ce qui m'intéresse le plus est-ce - ces techniques (hachage côté client, demande-réponse) ajoutent-elles un gain de sécurité significatif dans le cas où https est utilisé? Si oui, pourquoi?

116
johndodo

Si vous hachez côté client, le mot de passe haché devient le mot de passe réel (l'algorithme de hachage n'étant rien de plus qu'un moyen de convertir un tilisateur mnémonique en mot de passe réel).

Cela signifie que vous stockerez le mot de passe complet "plain-text" (le hachage) dans la base de données, et vous aurez perdu tout avantage du hachage en premier lieu.

Si vous décidez d'emprunter cette voie, vous pourriez aussi bien renoncer à tout hachage et simplement transmettre et stocker le mot de passe brut de l'utilisateur (que, d'ailleurs, je ne recommanderais pas particulièrement).

124
Nicole Calinoiu

Le hachage sur le client n'a de sens que si vous ne faites pas confiance au serveur d'une manière ou d'une autre et que vous ne voulez pas lui montrer le mot de passe "réel" (celui dont l'utilisateur humain se souvient). Pourquoi ne voudriez-vous pas montrer le mot de passe au site même sur lequel ledit mot de passe peut être utilisé? Parce que vous avez réutilisé le mot de passe ailleurs ! Maintenant, c'est généralement mauvais, mais il existe une version relativement sûre qui s'incarne dans une myriade d'extensions de navigateur ou de bookmarklets tels que celui-ci ou celui-là (je ne garantis pas leur qualité). Ce sont des outils où l'utilisateur humain se souvient d'un "mot de passe principal", à partir duquel un mot de passe spécifique au site est généré, en utilisant le nom de domaine du site comme une sorte de sel, de sorte que deux sites distincts obtiennent des mots de passe distincts.

Bien que ce scénario soit logique, le faire avec Javascript envoyé par le serveur lui-même ne le fait pas. En effet, le point de hachage du côté client du mot de passe est que le serveur est potentiellement hostile (par exemple subverti par un attaquant), et donc le code Javascript envoyé par ce serveur est, à tout le moins, suspect. Vous ne voulez pas entrer votre précieux mot de passe dans un Javascript hostile ...


Un autre cas de hachage côté client concerne environ hachage lent. Puisque les mots de passe sont, par définition, faibles, vous voulez contrecarrer attaques par dictionnaire . Vous supposez que le méchant a obtenu une copie de la base de données du serveur et "essaiera les mots de passe" sur ses propres machines (voir ce billet de blog pour une discussion à ce sujet). Pour ralentir l'adversaire, vous utilisez un processus de hachage intrinsèquement lent (tel que bcrypt ), mais cela rendra le traitement lent pour tout le monde, y compris le serveur. Pour aider le serveur, vous voudrez peut-être décharger une partie du travail sur le client, donc faites-en au moins une partie dans du code Javascript exécuté dans le navigateur du client ...

Malheureusement, Javascript est terriblement lent dans ce type de travail (généralement 20 à 100 fois plus lent qu'un code C décent), et le système client ne sera pas en mesure de contribuer une partie substantielle à l'effort de hachage. L'idée est bonne mais devra attendre une meilleure technologie (cela aurait fonctionné avec un client Java, cependant: avec une JVM décente, optimisée Java est environ 2 à 4 fois plus lent que le code C optimisé, pour un travail de hachage).


Pour résumer, il n'y a pas vraiment de bonnes raisons de faire du hachage de mot de passe côté client, à partir du code Javascript envoyé par le serveur lui-même. Envoyez simplement le mot de passe "tel quel" au serveur via un tunnel HTTPS (la page de connexion, l'URL de destination du formulaire et la page protégée par le mot de passe doivent tous être servi via SSL, sinon vous avez des problèmes de sécurité plus urgents que l'utilisation de mots de passe).

32
Thomas Pornin

Je trouve que toutes vos préoccupations sont valables, mais ma recommandation serait de le faire côté serveur.

Il y a toujours une assez grande chance qu'un utilisateur laisse son terminal déverrouillé, ce qui permet une manipulation. Et aussi; si votre logique de hachage est côté client, vous l'exposez.

Une autre option serait de générer les mots de passe côté serveur; alors vous n'envoyez pas de mot de passe en texte clair. Mais vous devrez toujours communiquer le mot de passe à l'utilisateur. Et comme la plupart des utilisateurs n'utilisent toujours pas de messagerie cryptée, je considère que c'est moins sécurisé.

J'ai vu des solutions pour envoyer des mots de passe via un tunnel crypté vers un téléphone portable; mais je doute que la sécurité soit meilleure que le SSL. Peut-être que quelqu'un pourrait prouver/réfuter cela?

11
rmorero

Le hachage côté serveur est important comme toutes les autres réponses l'ont indiqué, mais je voudrais ajouter que le hachage côté client serait une fonctionnalité de sécurité intéressante en plus au hachage côté serveur.

Le hachage côté client présente des avantages dans les scénarios suivants:

  1. Protège le mot de passe de l'utilisateur lorsque le serveur est compromis. C'est à dire. si le client n'est pas compromis, mais le serveur l'est, si le client hache le mot de passe, le serveur pourrait toujours accéder au système, mais vous avez protégé le mot de passe de l'utilisateur, ce qui est important s'il utilise ce mot de passe ailleurs.
  2. Protège le mot de passe de l'utilisateur lorsqu'il pense qu'il se connecte à un serveur mais qu'il se connecte vraiment à un autre (erreur utilisateur). Par exemple, si j'ai deux comptes bancaires et que je tape accidentellement l'un des mots de passe de ma banque dans le mauvais site Web de la banque, si la banque a haché le mot de passe côté client, cette banque ne connaîtrait pas le mot de passe de mon autre banque. Je pense que ce serait une chose "polie" de hacher côté client afin que leur mot de passe en texte brut ne soit jamais transmis sur le fil.

Surtout, il montre du respect pour le mot de passe de l'utilisateur. L'utilisateur partage un secret qui peut ne pas être exclusif à votre logiciel, donc si vous respectez ce secret, vous devez faire tout ce qui est en votre pouvoir pour le protéger.

10
Samuel

Si vous êtes dans un tunnel HTTPS, le mot de passe ou le hachage doit être sécurisé contre la surveillance Ethernet.

Côté client, vous pourriez peut-être saler le hachage avec un identifiant de session.
Cela pourrait être plus difficile à simuler pour Javascript malveillant.

2
bua

Vous pouvez faire les deux, vous le hachez sur le client, donc si l'attaquant peut obtenir la sécurité https, il ne pourra pas voir le mot de passe en texte brut. Ensuite, hachez-le à nouveau sur le serveur, donc si l'attaquant obtient les mots de passe stockés sur le serveur, il ne peut pas simplement envoyer cela au serveur et accéder au mot de passe.

1
nat that

Le hachage du mot de passe côté client nécessitera Javascript. Certaines personnes désactivent Javascript sur leur navigateur. Vous devez gérer ce scénario.

J'ai vu un logiciel de forum qui exécute le hachage de mot de passe côté client et envoie le hachage lors de la connexion si possible, sinon le mot de passe est envoyé en texte brut. Cela fonctionne donc dans les deux situations.

L'envoi du mot de passe en clair n'est pas une préoccupation majeure si vous utilisez https. Idéalement, votre serveur devrait alors refuser de diffuser des pages en http afin d'éviter l'homme au milieu de l'attaque. Le raisonnement est le suivant: un attaquant pourrait "rétrograder" de force votre connexion de https vers http et commencer à renifler du trafic (par exemple avec un outil comme SSL Strip).

1
Anonymous

La réponse acceptée de @ Nicole Calinoiu est bien sûr correcte mais peut-être trop difficile à comprendre au début.

Le fait est que le mot de passe doit être haché sur le serveur afin que la personne malveillante ne puisse pas utiliser les hachages qu'il a piratés de la base de données du serveur pour accéder à votre compte ou à vos données.

Comme déjà dit, si vous hachez côté client et que le back-end le prend en charge, le hachage devient votre mot de passe et si le hachage est volé via un hack, le pirate a le mot de passe.

@ Thomas Pornin réponse a également trouvé un très bon point pourquoi vous voudriez hacher le mot de passe sur le client, mais la chose qu'il décrit dans sa première histoire ne peut être faite que si le serveur principal prend en charge la gestion des mots de passe hachés (c'est-à-dire ne pas hacher le mot de passe s'il est déjà haché, mais que quelqu'un essaie de prendre en charge quelque chose comme ça est très peu probable ), ce qui ne sera généralement pas le cas, je suppose. La deuxième histoire de lui est très bonne.

0
Ini