web-dev-qa-db-fra.com

Pourquoi ajouter un nom d'utilisateur à Salt avant de hacher un mot de passe?

J'ai vu des exemples de hachage de mot de passe qui étaient: H (nom d'utilisateur + sel + mot de passe). Quel est le but de l'ajout d'un nom d'utilisateur? Y a-t-il un but?

78
PaintingInAir

Non, il n'y a aucun but. C'est le théâtre de la sécurité *. Le but d'un sel est de rendre infaisables les attaques parallèles contre tous les mots de passe hachés et de casser les tables Rainbow. L'ajout du nom d'utilisateur ici n'améliore pas ce comportement ni n'augmente aucun autre aspect de la sécurité. Il a en fait un peu d'inconvénient car vous rencontrerez maintenant des problèmes si vous changez le nom d'utilisateur, et vous devez maintenir un système plus complexe et non standard. Dans un sens purement cryptographique, il n'y a pas d'inconvénient. En pratique cependant, plus de complexité signifie plus de bugs.

Les propriétés des sels et des noms d'utilisateur

Vous pourriez penser que le nom d'utilisateur lui-même n'est peut-être pas public, donc cela ne pouvait pas nuire à l'utiliser comme un secret supplémentaire, mais le fait est que la base de données contiendra probablement déjà le nom d'utilisateur en texte clair, invalidant cet avantage déjà discutable. Les gens devraient s'en tenir aux techniques d'authentification préexistantes. Mais regardons les propriétés de chacun de ces objets:

Un sel c'est:

  • Pas secret - Les sels sont stockés en texte clair.

  • Sécurisé - Ils sont générés de manière aléatoire et sont longs.

  • Unique - Le sel de chaque utilisateur est intentionnellement différent.

Un mot de passe est:

  • Secret - En supposant qu'ils ne soient pas mis sur une note collante.

  • Sécurisé - Si ce n'est pas hunter2 . Le mot de passe doit être bon .

  • Unique - Idéalement, au moins, mais tous les mots de passe ne sont pas idéaux.

Comparez maintenant cela à un nom d'utilisateur. Un nom d'utilisateur est:

  • Pas secret - Ils sont publics ou au moins stockés en texte brut .

  • Pas sécurisé - Personne ne pense à choisir un nom d'utilisateur long et complexe.

  • Pas unique - Les noms d'utilisateur sont sûrs à partager entre les sites.

Les traits d'un bon sel

Maintenant, que fait exactement un sel ? En général, un bon sel offre trois avantages:

  1. Il empêche un attaquant d'attaquer le hachage de chaque utilisateur à la fois . L'attaquant n'est plus en mesure de hacher un mot de passe candidat et de le tester par rapport à chaque entrée à la fois. Ils sont obligés de recalculer un mot de passe donné à tester pour le hachage de chaque utilisateur. Cet avantage fourni par un sel augmente de façon linéaire à mesure que le nombre d'entrées de hachage cible distinct augmente. Bien sûr, les sels sont toujours importants même si un seul hachage a besoin de protection, comme je l'explique ci-dessous.

  2. Cela rend les tables Rainbow irréalisables . A Rainbow table est une table précalculée hautement optimisée qui fait correspondre les mots de passe aux hachages. Ils occupent moins d'espace qu'une gigantesque table de recherche, mais prennent beaucoup de temps à générer (un compromis espace-temps). Pour que les tables Rainbow fonctionnent, un mot de passe donné doit toujours se résoudre au même hachage. Les sels brisent cette hypothèse, ce qui rend les tableaux Rainbow impraticables car ils devraient avoir une nouvelle entrée pour chaque sel possible.

  3. Il empêche ciblé de précalcul via les tables Rainbow, au moins lorsque le hachage est vraiment aléatoire. Un attaquant ne peut commencer l'attaque qu'après avoir mis la main sur les hachages (et avec eux, les sels). Si le sel est déjà public mais que le hachage ne l'est pas, alors l'attaque peut être optimisée en générant une table Rainbow pour ce sel spécifique. C'est une des raisons pour lesquelles WPA2 est un protocole aussi laid. Le sel est l'ESSID (nom du réseau), donc quelqu'un peut commencer l'attaque pour le routeur de sa cible avant même d'avoir mis la main sur la poignée de main à 4 voies.

Quel avantage pourrait donc concaténer une valeur avant le hachage lorsque cette valeur est publique, non sécurisée et réutilisée? Il ne finit pas par exiger de l'attaquant Dig pour plus d'informations. Cela n'ajoute pas à la sécurité d'un sel. Cela n'augmente pas la complexité du mot de passe. Il n'y a aucun avantage.

Hachage correct du mot de passe

Alors que devraient-ils faire pour augmenter la sécurité ? Ils peuvent utiliser un KDF tel que PBKDF2, bcrypt, scrypt ou argon2 au lieu d'un seul hachage. Ils peuvent ajouter un poivre , qui est une valeur globale aléatoire stockée en dehors de la base de données et ajoutée au mot de passe et au sel, ce qui rend nécessaire de voler le poivre pour tenter d'attaquer les hachages plutôt que de simplement vider le base de données utilisant SQLi.

EDIT: Comme le soulignent certains commentaires, il y a un scénario artificiel où le nom d'utilisateur serait bénéfique à ajouter au mélange. Ce scénario serait celui où l'implémentation est suffisamment cassée pour que le sel ne soit pas réellement un sel, et le nom d'utilisateur est la seule valeur par utilisateur unique ou semi-unique dans la base de données, auquel cas le mélange dans le nom d'utilisateur serait mieux que rien. Mais vraiment, si vous n'avez pas de sel, vous devriez commencer à en utiliser un au lieu d'essayer d'utiliser des noms d'utilisateur. Utilisez une sécurité réelle et ne vous inquiétez pas lorsque la sécurité de vos utilisateurs est en jeu.

* Dans ce contexte, je définis le théâtre de la sécurité comme la pratique de mettre en œuvre des mesures de sécurité qui n'améliorent pas réellement la sécurité de manière significative et ne sont là que pour fournir l'illusion d'une meilleure sécurité.

152
forest

Si le sel est suffisamment aléatoire comme il est censé l'être, l'ajout du nom d'utilisateur n'ajoute pas de protection supplémentaire. Mais cela ne cause pas non plus de mal en plus de rendre le code plus complexe, ce qui augmente la probabilité de bogues. Lors d'une révision de code, cela peut être considéré comme un signe que le développeur ne comprend pas pleinement ce qu'il fait.

Si, à la place, le sel est principalement statique ou dérivé du mot de passe, le nom d'utilisateur peut aider, car dans ce cas, le nom d'utilisateur sert essentiellement le but que le sel n'a pas réussi à servir. Mais, ce n'est pas la méthode recommandée car le sel est censé être aléatoire et un nom d'utilisateur ne l'est pas.

Voir Est-ce une bonne idée d'utiliser le nom d'utilisateur de l'utilisateur comme sel lors du hachage d'un mot de passe comme hash (username_str + password_str)? et Que doit-on utiliser comme sel? pour une discussion plus approfondie de ce qu'un bon sel devrait être et pourquoi le nom d'utilisateur n'est pas un bon sel. Voir aussi Pourquoi les hachages salés sont-ils plus sûrs pour le stockage des mots de passe? pour comprendre le but du sel en premier lieu.

11
Steffen Ullrich

Comme l'a souligné @Damien_The_Unbeliever dans un commentaire, il peut empêcher l'emprunt d'identité de l'utilisateur dans un scénario où le système a été partiellement compromis.

Imaginez le scénario suivant. D'une manière ou d'une autre, un attaquant a obtenu un accès en lecture/écriture à la table db utilisée pour la connexion, contenant les noms d'utilisateur, les hachages de mot de passe et les sels - peut-être via une attaque par injection SQL. Cet attaquant n'a pas d'autre accès élevé au système, mais souhaite se faire passer pour un utilisateur du système d'une manière introuvable (ou difficile à tracer).

  • Tout d'abord, l'attaquant enregistre le hachage et le sel de mot de passe d'origine pour le compte de la victime.
  • Ensuite, l'attaquant enregistre son propre compte et copie le hachage et le sel de mot de passe de leur compte dans le compte de la victime.
  • Désormais, l'attaquant peut se connecter au compte de la victime à l'aide de son propre mot de passe.
  • Lorsque l'attaquant a terminé, ils restaurent le hachage et le sel de mot de passe de la victime, ce qui rend difficile pour la victime de réaliser ce qui s'est passé.

Alors que dans certains systèmes, un attaquant avec ce niveau d'accès pourrait simplement générer un hachage de mot de passe en utilisant le nom d'utilisateur de la victime, salt et un mot de passe arbitraire (plutôt que de copier le leur), ce n'est pas possible si le système utilise un pepper en plus du sel (une constante définie globalement ajoutée à l'entrée pour tous les hachages de mot de passe, qui est stockée quelque part différemment des hachages et des sels de mot de passe). Sans compromettre le poivre, la seule façon dont l'attaquant dans ce scénario peut définir un hachage de mot de passe avec un mot de passe connu pour la victime est d'en copier un généré par le système, comme décrit ci-dessus.

Notez que l'authentification à deux facteurs ne peut probablement même pas empêcher cela. Si l'attaquant a également accès aux codes d'initialisation 2FA pour les utilisateurs (peut-être stockés dans la même table db), le code de l'attaquant peut également être temporairement écrit dans le compte de la victime.

En revanche, si le nom d'utilisateur est utilisé dans le calcul du hachage du mot de passe, cette attaque d'emprunt d'identité particulière ne fonctionnera pas. Même une fois que l'attaquant copie son hachage de mot de passe, sel et code 2FA dans le compte de la victime, l'utilisation du mot de passe de l'attaquant sur le compte de la victime n'entraînera pas le même hachage de mot de passe que pour le compte de l'attaquant, et donc la connexion échouera.

Il est discutable que les avantages valent la complexité supplémentaire et la possibilité de bogues bien sûr, car ce scénario nécessite que l'attaquant ait déjà sérieusement compromis le système, et dans ce scénario, l'attaquant ne récupère pas le mot de passe réel de l'utilisateur. Mais, on peut affirmer qu'il s'agit d'une protection supplémentaire.

10
zacronos

Pour commencer, le hachage de mot de passe doit être effectué avec une fonction de hachage de mot de passe dédiée telle que bcrypt, Argon2, scrypt ou PBKDF2. Dans ce cas, vous n'avez pas à gérer la concaténation du sel et du mot de passe comme une primitive; la fonction les prend comme arguments séparés. Voir "Comment hacher en toute sécurité les mots de passe?" , l'un des meilleurs Q & A sur ce site pour ce sujet.

Le but du sel dans le hachage de mot de passe est de randomiser la fonction de hachage qui est appliquée à chaque entrée de mot de passe. Donc, trois règles qui s'appliquent généralement aux hachages de mots de passe spécialisés modernes sont les suivantes:

  1. Chaque fois que vous enregistrez un nouveau mot de passe, vous devez générer un nouveau sel. (Notez que cela signifie que lorsqu'un utilisateur modifie son mot de passe, vous devez générer un nouveau sel pour ce mot de passe, pas réutiliser le sel pour l'ancien. Les sels sont liés aux états d'une entrée de base de données de mots de passe , pas aux utilisateurs.)
  2. La valeur du sel doit être indépendante du mot de passe lui-même; la connaissance du mot de passe ne devrait pas aider à deviner le sel, sinon un attaquant pourrait utiliser ces connaissances pour précalculer une table d'attaque. Un exemple évident ici est que vous ne devez pas utiliser le mot de passe lui-même comme sel. (C'est moins stupide que cela puisse paraître - vous ne stockeriez pas le sel le long du mot de passe dans ce cas - mais il est stupide, car deux utilisateurs avec le même mot de passe aurait le même hachage.)
  3. La chance que deux sels soient égaux devrait être très faible. De préférence non seulement dans votre application, mais dans le monde entier.

Nous pouvons maintenant répondre à votre question en faisant ces observations:

  • Un sel composé d'un nombre suffisant d'octets aléatoires satisfait déjà à ces critères. 16 octets aléatoires (provenant d'un générateur de nombres aléatoires cryptographiquement fort) semblent raisonnables.
  • La concaténation du nom d'utilisateur à un tel sel aléatoire n'aide pas.
  • Si les sels sont générés d'une manière prévisible mais quelque peu non répétable, par exemple, en tant que compteur incrémenté à chaque fois que vous inscrivez un nouveau mot de passe ou en tant qu'horodatage, la concaténation de valeurs supplémentaires comme le nom d'utilisateur ou le nom de domaine de votre site peut aider à créer c'est plus unique. Mais l'utilisation de sels aléatoires serait plus simple (pas besoin de suivre un état de compteur persistant).
6
Luis Casillas