Edit: mis à jour pour mettre davantage l'accent sur l'objectif - tranquillité d'esprit pour l'utilisateur, et non pas renforcer la sécurité.
Après avoir lu quelques discussions ici sur le hachage côté client des mots de passe, je me demande toujours s'il ne serait pas correct de l'utiliser dans une situation particulière.
Plus précisément, j'aimerais que le client - un Java - hache son mot de passe en utilisant quelque chose comme PBKDF2, en utilisant comme sel une combinaison de son adresse e-mail et d'un constant octet spécifique à l'application . L'idée étant que le hachage est reproductible pour l'authentification, mais il est à espérer qu'il n'est pas vulnérable aux attaques de rétro-ingénierie (pour découvrir le mot de passe littéral) autre que la force brute si le les données du serveur sont compromises.
Objectif:
Le hachage côté client est pour la tranquillité d'esprit de l'utilisateur que son mot de passe littéral n'est jamais reçu par le serveur, même s'il a l'assurance de le hacher de toute façon. Un autre avantage secondaire (ou peut-être un passif?) Est que le coût de hachage d'un PBKDF2 itéré ou similaire incombe au client.
Les caractéristiques de l'environnement sont:
Préoccupations:
Pensées?
Le hachage côté client ne résout pas le problème principal que le hachage de mot de passe est censé résoudre - ce qui se passe si un attaquant accède à la base de données de mots de passe hachés. Étant donné que les mots de passe (hachés) envoyés par les clients sont stockés tels quels dans la base de données, un tel attaquant peut usurper l'identité de tous les utilisateurs en envoyant au serveur les mots de passe hachés de la base de données tels quels.
D'un autre côté, le hachage côté client est agréable en ce qu'il assure l'utilisateur que le serveur n'a pas connaissance du mot de passe - ce qui est utile si l'utilisateur utilise le même mot de passe pour plusieurs services (comme la plupart des utilisateurs le font).
Une solution possible pour cela consiste à hacher à la fois côté client et côté serveur. Vous pouvez toujours décharger la lourde opération PBKDF2 vers le client et effectuer une seule opération de hachage (côté client, le mot de passe haché PBKDF2) côté serveur. Le PBKDF2 dans le client empêchera les attaques par dictionnaire et l'opération de hachage unique côté serveur empêchera d'utiliser les mots de passe hachés d'une base de données volée tels quels.
Il y a peu de temps où le hachage côté client en vaut la peine. Une telle circonstance est lorsque le processus de hachage est intensif en calcul, ce qui peut être le cas avec PBKDF2.
Répondre à vos préoccupations:
Si vous hachez le mot de passe côté client, quel que soit le résultat IS le mot de passe, vous n'obtiendrez aucune sécurité réelle. Tout piratage ou fuite d'informations qui aurait révélé le mot de passe en texte brut révélera à la place le mot de passe haché, qui est le vrai mot de passe.
Cela ne doit pas être confondu avec les schémas d'authentification à connaissance zéro, où un échange de messages prouve que le client connaît le vrai mot de passe, sans le transmettre réellement.
Il semble que vous essayez d'inventer votre propre protocole cryptographique. D'après la description de votre approche, il ne semble pas que vous ayez les antécédents pour le faire de manière sécurisée. Je recommande fortement d'utiliser les protocoles existants au lieu de créer les vôtres.
Premièrement, le modèle de menace que vous pensez contourner n'est pas clair. Vous citez quelque chose appelé "attaque de rétro-ingénierie" qui n'a pas de véritable définition ou signification.
Deuxièmement, votre compréhension du but d'un sel et des meilleures pratiques pour sa génération semble faire défaut. Les sels ne doivent pas être gardés secrets. Vous pouvez (et devez) générer un sel unique à partir d'un CSPRNG pour chaque nouveau jeton d'authentification, et non à partir de quelque chose comme une adresse e-mail (qui pourrait changer). Les sels fixes spécifiques à l'application sont parfois appelés "poivrons", et je ne connais aucune littérature cryptographique qui soutienne ou encourage leur utilisation.
Troisièmement, PBKDF2 est correct, mais sérieusement juste tilisez BCrypt . BCrypt a été conçu pour cela et est largement utilisé. De bonnes implémentations BCrypt géreront la génération de sel et l'étalonnage/détection automatique des facteurs de travail pour vous. Vous devrez implémenter ces choses vous-même pour utiliser PBKDF2, et vous ferez presque inévitablement des erreurs.
Quatrièmement, il existe une approche existante de ce que vous semblez essayer de faire. L'authentification sans connaissance peut être effectuée avec SRP . Le mot de passe de l'utilisateur n'est jamais transmis sur le fil, et un homme au milieu ne peut rien renifler pour s'authentifier. Cependant, il est apparemment difficile à implémenter correctement et il n'y a pas beaucoup de bibliothèques existantes pour le faire, ce qui devrait vous donner une indication de la difficulté réelle du problème.
Pour faire court: n'inventez pas votre propre crypto. Utilisez des solutions et des protocoles largement mis en œuvre et qui ont résisté à l'épreuve du temps.
Le hachage du client peut être une bonne idée dans certaines circonstances et pour certaines raisons, mais je ne ferais pas de la "tranquillité d'esprit de l'utilisateur" l'une d'entre elles. Je suis tout à fait pour que les utilisateurs soient dans un état d'esprit harmonieux et en harmonie avec l'Univers, mais je trouve douteuse l'idée de promouvoir un moyen d'induire aux utilisateurs de réutiliser le même mot de passe sur plusieurs sites.
Un bon cas pour le hachage côté client est la façon dont certains "coffres-forts de mot de passe" fonctionnent: ils calculent un mot de passe spécifique au site en hachant le "mot de passe principal" de l'utilisateur avec le nom du site. Cela donne la plupart de la facilité d'utilisation de toujours utiliser le même mot de passe partout, tout en ne donnant pas réellement votre mot de passe principal à des dizaines de sites distincts. Mais cela ne fonctionne que tant que l'algorithme de dérivation de mot de passe est générique et ne change pas; cela semble être beaucoup mieux traité par une extension de navigateur Web que par une applet provenant des sites eux-mêmes (tous les sites devraient coopérer afin d'utiliser des applets qui utilisent le même algorithme de dérivation de mot de passe, avec des données spécifiques au site).
Un autre bon cas pour le hachage de mot de passe côté client est lorsqu'un hachage lent est utilisé (afin de rendre le craquage de mot de passe plus difficile pour un attaquant qui pourrait récupérer une copie de la base de données des mots de passe hachés); il est tentant de décharger le coût sur le client, car, lorsque le client veut se connecter, il est surtout inactif et activement intéressé à se connecter. Cependant, le hachage lent est une course aux armements entre l'attaquant et le défenseur. L'utilisation de Java induira un ralentissement (d'un facteur typique de 3), et certains systèmes clients peuvent être assez faibles (par exemple les smartphones bon marché ou les ordinateurs de dix ans). C'est comme ramasser une épée au lieu d'un fusil d'assaut avant d'entrer dans une bataille où l'adversaire apportera un char).
Mais si ce que vous voulez, en tant qu'utilisateur, est de protéger votre mot de passe contre les procédures de stockage bâclées par un site, alors la bonne façon de le faire est pour choisir un mot de passe différent pour chaque site. (Personnellement, je garde un fichier de mots de passe et tous mes mots de passe sont générés de manière aléatoire.)
Un employé de Google travaille sur quelque chose de similaire appelé TLS-OBC. Ce brouillon RFC permet au client de hacher le mot de passe et de le lier à une session TLS.
Plus précisément, vous pouvez être intéressé par ce site Web http://www.browserauth.net/Origin-bound-certificates
et ce lien sur l'authentification forte de l'utilisateur http://www.browserauth.net/strong-user-authentication
::Mise à jour
OBC et peut-être l'autre est maintenant intégré dans la norme d'authentification FIDO.
L'objectif principal du hachage de mot de passe est d'empêcher quiconque, sauf l'utilisateur, d'apprendre le mot de passe. Les gens les réutilisent et ils ne sont généralement pas super forts s'ils sont mémorisés. C'est pourquoi nous nous soucions des hachages lents (PBKDF2, Bcrypt, Scrypt, Argon2, peu importe) au lieu d'un hachage rapide: il protège mieux le mot de passe de l'utilisateur, même s'il n'a aucun avantage pour l'application. Un avantage secondaire d'avoir le hachage du serveur quoi qu'il arrive avant de le stocker dans la base de données, est que quelqu'un qui compromet la base de données ne peut se connecter avec aucune des valeurs ils ont trouvé (ils doivent d'abord les casser).
Nous voulons conserver les deux avantages. À cette fin, je soutiens que nous devrions hacher sur le serveur et le client.
Pourquoi sur le serveur?
. .
Pourquoi sur le client?
<input type=password hash=v1>
, qui ferait tout le hachage pour vous (il serait salé avec le champ nom de domaine et nom d'utilisateur, mais tous ces détails de cette proposition dépassent le cadre de cette réponse).[~ # ~] faq [~ # ~]
Je pense que la seule raison pour laquelle le hachage côté client n'est pas la norme, c'est parce que personne d'autre ne le fait. Chaque fois que quelqu'un le propose, tout le monde pense "alors pourquoi ne le faisons-nous pas déjà? Il doit y avoir une raison!" et commencer à remettre en question les avantages, ou inventer des raisons illogiques. Si les raisons ci-dessus ne suffisent pas déjà, permettez-moi d'essayer de réfuter certaines des questions que j'ai entendues auparavant: