web-dev-qa-db-fra.com

La nécessité de cacher le sel pour un hash

Au travail, nous avons deux théories concurrentes pour les sels. Les produits sur lesquels je travaille utilisent quelque chose comme un nom d'utilisateur ou un numéro de téléphone pour saler le hash. Essentiellement, quelque chose de différent pour chaque utilisateur, mais qui est facilement disponible pour nous. L'autre produit génère de manière aléatoire un sel pour chaque utilisateur et change chaque fois que l'utilisateur modifie le mot de passe. Le sel est ensuite chiffré dans la base de données.

Ma question est de savoir si la deuxième approche est vraiment nécessaire? Je peux comprendre d'un point de vue purement théorique qu'il est plus sûr que la première approche, mais qu'en est-il du point de vue pratique? À l'heure actuelle, pour authentifier un utilisateur, le sel doit être déchiffré et appliqué aux informations de connexion. 

Après réflexion, je ne vois tout simplement pas un réel gain de sécurité de cette approche. Changer le sel d'un compte à l'autre rend encore extrêmement difficile toute tentative de forcer brutalement l'algorithme de hachage, même si l'attaquant savait comment déterminer rapidement ce que c'était pour chaque compte. Cela part du principe que les mots de passe sont suffisamment forts. (Il est évidemment beaucoup plus facile de trouver le hachage correct pour un ensemble de mots de passe contenant tous les deux chiffres que de trouver le hachage correct de mots de passe de 8 chiffres). Est-ce que je me trompe de logique ou y a-t-il quelque chose qui me manque?

EDIT: D'accord, voici donc la raison pour laquelle je pense qu'il est vraiment discutable de chiffrer le sel. (Je sais si je suis sur la bonne voie). 

Pour l'explication suivante, supposons que les mots de passe sont toujours composés de 8 caractères et que le sel est composé de 5 et que tous les mots de passe sont composés de lettres minuscules (cela facilite simplement les calculs).

Avoir un sel différent pour chaque entrée signifie que je ne peux pas utiliser la même table Rainbow (techniquement, je le pourrais si j'avais une taille suffisante, mais ignorons cela pour le moment). Ce que je comprends, c’est la vraie clé du succès, car pour craquer tous les comptes, je dois réinventer la roue pour ainsi dire. Maintenant, si je sais comment appliquer le sel correct à un mot de passe pour générer le hachage, je le ferais car un sel étend simplement la longueur/complexité de la phrase hachée. Donc, je couperais le nombre de combinaisons possibles que je devrais générer pour "savoir" que j'ai le mot de passe + sel de 13 ^ 26 à 8 ^ 26 car je sais ce que c'est que le sel. Cela facilite les choses, mais reste très difficile. 

Donc, sur le cryptage du sel. Si je sais que le sel est crypté, je ne tenterais pas de le décrypter (en supposant que je sache qu'il a un niveau de cryptage suffisant), tout d'abord. Je l'ignorerais. Au lieu d'essayer de comprendre comment le déchiffrer, pour revenir à l'exemple précédent, je générerais simplement un plus grand tableau Rainbow contenant toutes les clés du 13 ^ 26. Ne pas savoir le sel me ralentirait certainement, mais je ne pense pas que cela ajouterait la tâche monumentale d'essayer de déchiffrer le chiffrement du sel en premier. C'est pourquoi je ne pense pas que ça en vaut la peine. Pensées?

Voici un lien décrivant la durée de validité des mots de passe lors d’une attaque par force brute: http://www.lockdown.co.uk/?pg=combi

95
kemiller2002

La réponse ici est de vous demander ce que vous essayez vraiment de protéger? Si une personne a accès à votre base de données, elle aura accès aux sels chiffrés et probablement également à votre code. Avec tout ce qu'ils pourraient décrypter les sels cryptés? Si c'est le cas, le cryptage est de toute façon plutôt inutile. Le sel est vraiment là pour le rendre, il est donc impossible de former une table Rainbow pour casser votre base de données de mot de passe en une seule fois si elle est cassée. De ce point de vue, tant que chaque sel est unique, il n'y a pas de différence, une attaque par force brute sera nécessaire avec vos sels ou les sels cryptés pour chaque mot de passe individuellement.

42
tloach

Cacher un sel n'est pas nécessaire.

Un sel différent devrait être utilisé pour chaque hash. En pratique, cela est facile à obtenir en obtenant au moins 8 octets du générateur de nombres aléatoires de qualité cryptographique.

De un réponse précédente de moi :

Salt aide à déjouer les attaques par dictionnaire pré-calculées.

Supposons qu'un attaquant dispose d'une liste de mots de passe probables. Il peut hacher chacun et le comparer au hash du mot de passe de sa victime, et voir si c'est allumettes. Si la liste est longue, cela pourrait prendre beaucoup de temps. Il n'a pas veut passer autant de temps sur sa prochaine cible, alors il enregistre le résultat dans un "dictionnaire" où un dièse pointe vers l'entrée correspondante. Si la liste des mots de passe est très longue, il peut utiliser des techniques comme un Rainbow Table pour économiser de l'espace.

Cependant, supposons que sa prochaine cible ait salé leur mot de passe. Même si le L'attaquant sait ce qu'est le sel, sa table précalculée est sans valeur - le sel change le hachage résultant de chaque mot de passe. Il doit re-hacher tous les mots de passe de sa liste, en apposant le .__ de la cible. sel à l'entrée. Chaque sel différent nécessite un différent dictionnaire, et si suffisamment de sels sont utilisés, l'attaquant n'aura plus de place pour stocker des dictionnaires pour tous. L'échange d'espace pour gagner du temps, c'est non. plus une option; l'attaquant doit recourir au hachage de chaque mot de passe dans sa liste pour chaque cible, il veut attaquer.

Donc, il n'est pas nécessaire de garder le secret du sel. S'assurer que le l'attaquant ne dispose pas d'un dictionnaire pré-calculé correspondant à celui-ci le sel particulier est suffisant.


Après avoir réfléchi un peu plus à ce sujet, je me suis rendu compte qu'il est dangereux de se leurrer en pensant que l'on peut cacher le sel. Il est bien mieux de supposer que le sel ne peut pas être caché et de concevoir le système pour qu'il soit sûr en dépit de cela. Je fournis une explication plus détaillée dans une autre réponse.

92
erickson

Un sel caché n'est plus du sel. C'est du poivre. Il a son utilisation. C'est différent du sel.

Pepper est une clé secrète ajoutée au mot de passe + salt qui transforme le hachage en un code d'authentification de message basé sur le hachage (HMAC). Un pirate informatique ayant accès à la sortie de hachage et au sel peut théoriquement forcer la force brute à deviner une entrée qui va générer le hachage (et donc passer la validation dans la zone de texte du mot de passe). En ajoutant du poivre, vous augmentez l’espace du problème de manière cryptographique et aléatoire, rendant le problème insoluble sans matériel sérieux.

Pour plus d'informations sur le poivre, consultez ici .

Voir aussi hmac .

3
John Wu

Si je comprends bien, le "sel" rend la fissuration plus difficile, mais n'essaie pas de cacher les données supplémentaires. Si vous essayez d’obtenir plus de sécurité en rendant le sel "secret", vous voulez vraiment plus de bits dans vos clés de cryptage.

3
gbarry

La seconde approche n’est que légèrement plus sûre. Les sels protègent les utilisateurs des attaques par dictionnaire et des attaques par table Rainbow. Ils rendent plus difficile pour un attaquant ambitieux de compromettre l'ensemble de votre système, mais restent vulnérables aux attaques ciblant un utilisateur de votre système. Si vous utilisez des informations publiques, comme un numéro de téléphone, et que l'attaquant en prend connaissance, vous leur enregistrez une étape dans son attaque. Bien sûr, la question est sans objet si l'attaquant obtient votre base de données entière, sels et tout.

EDIT: Après avoir relu cette réponse et certains commentaires, il me semble que la confusion est peut-être due au fait que je ne compare que les deux cas très spécifiques présentés dans la question: sel aléatoire vs sel non aléatoire. La question de utiliser un numéro de téléphone comme un sel est sans objet si l'attaquant récupère l'intégralité de votre base de données, pas la question de l'utilisation d'un sel.

3
Bill the Lizard

... quelque chose comme un nom d'utilisateur ou un numéro de téléphone pour saler le hachage. ...

Ma question est de savoir si la deuxième approche est vraiment nécessaire? Je peux comprendre d’un point de vue purement théorique qu’elle est plus sûre que la première approche, mais qu’en est-il du point de vue pratique?

D'un point de vue pratique, un sel est un détail de mise en œuvre. Si vous modifiez la manière dont les informations utilisateur sont collectées ou conservées (et les noms d'utilisateur et les numéros de téléphone changent parfois pour utiliser vos exemples exacts), vous avez peut-être compromis votre sécurité. Souhaitez-vous qu'un tel changement extérieur ait des problèmes de sécurité beaucoup plus profonds?

Est-ce que l'arrêt de l'exigence pour chaque compte d'avoir un numéro de téléphone nécessite une révision complète de la sécurité pour s'assurer que vous n'avez pas ouvert ces comptes à un compromis de sécurité?

2
Anon

Voici un exemple simple montrant pourquoi il est mauvais d’avoir le même sel pour chaque hash

Considérons le tableau suivant

UserId  UserName,   Password
     1  Fred       Hash1 =  Sha(Salt1+Password1)    
     2  Ted        Hash2 =  Sha(Salt2+Password2)    

Cas 1 lorsque salt 1 est identique à salt2 Si Hash2 est remplacé par Hash1, l'utilisateur 2 peut se connecter avec le mot de passe utilisateur 1.

Cas 2 lorsque sel 1 n'est pas le même sel2 Si Hash2 est remplacé par Hash1, l'utilisateur 2 ne peut pas se connecter avec le mot de passe utilisateur 1.

2
Charles Faiga

Il existe deux techniques, avec des objectifs différents:

  • Le "sel" est utilisé pour faire en sorte que deux mots de passe sinon égaux chiffrent différemment. De cette façon, un intrus ne peut pas utiliser efficacement une attaque par dictionnaire contre toute une liste de mots de passe cryptés.

  • Le "secret" (partagé) est ajouté avant le hachage d'un message, de sorte qu'un intrus ne peut pas créer ses propres messages et les faire accepter.

1
Javier

J'ai tendance à cacher le sel. J'utilise 10 bits de sel en ajoutant un nombre aléatoire de 1 à 1024 au début du mot de passe avant de le hacher. En comparant le mot de passe que l'utilisateur a entré avec le hachage, je boucle de 1 à 1024 et essaie toutes les valeurs possibles de salt jusqu'à ce que je trouve la correspondance. Cela prend moins de 1/10 de seconde. J'ai eu l'idée de le faire de cette manière à partir de PHP password_hash et password_verify . Dans mon exemple, le "coût" est de 10 pour 10 bits de sel. Ou, d'après ce qu'un autre utilisateur a dit, "sel" caché s'appelle "poivre". Le sel n'est pas chiffré dans la base de données. C'est une brute forcée. Cela rendrait la table Rainbow nécessaire pour inverser le hash 1000 fois plus grand. J'utilise sha256 parce que c'est rapide, mais toujours considéré comme sécurisé.

0
Russell Hankins