(J'ai fait une recherche sur ce sujet, mais je n'ai trouvé aucune question/réponse complète qui l'a abordé, ni même de bonnes parties de questions qui pourraient être pertinentes.)
J'implémente une fonction Salt pour les mots de passe des utilisateurs sur ma page Web, et je me pose des questions.
Un sel est une extension ajoutée à un mot de passe puis hachée, ce qui signifie que le mot de passe est stocké dans la base de données sous la forme hash(password+salt)
. Mais où stocke-t-on le sel? Un sel, c'est simplement pour rendre les tables Rainbow "inutiles", non?
Un attaquant ne pourrait-il pas simplement construire une table Rainbow, puis convertir tous les hachages et retirer le sel? Après tout, le sel est stocké quelque part dans la base de données. Par conséquent, si l'on peut trouver les mots de passe hachés, on devrait pouvoir trouver les sels correspondants. Il me semble qu'un sel ne fait que rallonger les mots de passe, forçant la table Rainbow à fonctionner plus longtemps.
Alors, comment peut-on maximiser l'efficacité d'un sel? Je ne vois pas vraiment de multiples raisons de sécurité, à part allonger dynamiquement les mots de passe, mais là encore, on pourrait les convertir en bits dans une chaîne à la place.
Mes hypothèses sur le fonctionnement d'un sel sont-elles correctes? Sinon, comment dois-je le stocker et les mots de passe salés correctement?
Vous avez fondamentalement raison de dire que cela prolonge simplement le mot de passe, mais il y a des choses supplémentaires qu'il ajoute. De plus, le mot de passe moyen n'est pas aussi long ou sécurisé et ajouter de la longueur "gratuitement" est rarement mauvais. Le sel fait en sorte qu'un attaquant ne puisse pas hacher "mot de passe" une fois, puis chercher chaque utilisateur qui a un mot de passe "mot de passe".
Au lieu de cela, ils devraient générer des hachages de "password03j9834nfp-3028n408" et "passwordn0438wnvas89v5sne" et ... Cela augmente considérablement la protection de l'identification des mots de passe non sécurisés et a toujours un avantage positif sur l'augmentation de la difficulté à trouver des mots de passe sécurisés.
Là où votre compréhension s'égare, c'est quand vous dites "Un attaquant ne pourrait-il pas simplement construire une table Rainbow, puis convertir tous les hachages et retirer le sel?". Il y a quelques problèmes ici.
Le premier est celui des collisions. Une table Rainbow n'est pas garantie de produire l'entrée d'origine, elle est uniquement intéressée par la production d'une entrée AN qui a produit la sortie souhaitée. Étant donné que le sel sera ajouté à tout ce qu'un utilisateur entre, l'attaquant doit trouver l'entrée exacte qui a été utilisée pour le hachage.
Étant donné que l'entrée exacte doit être trouvée, l'avantage d'une table Rainbow pour tirer parti des collisions est perdu. De plus, la taille requise pour forcer brutalement tous les sels possibles serait trop grande pour quasiment n'importe quel attaquant.
Vous ne pouvez pas non plus simplement retirer le sel d'un hachage sans comprendre ce qu'était l'entrée d'origine. Vous devez rechercher une valeur se terminant par le sel qui correspond au hachage donné. Cela nécessite alors de produire une table Rainbow distincte pour chaque valeur de sel dans la base de données, ce qui annule la capacité de pré-calcul car il est impossible de créer une table Rainbow pour chaque sel possible.
Vous avez une idée fausse fondamentale du fonctionnement des tables Rainbow.
Une table Rainbow ou une table de hachage est construite par un attaquant avant d'une attaque. Supposons que je crée une table de hachage contenant tous les hachages de chaînes de moins de 7 caractères pour MD5
. Si je compromets votre base de données et que j'obtiens la liste des hachages, tout ce que j'ai à faire est de rechercher le hachage sur la table pour obtenir votre mot de passe.
Avec un sel, vous ne pouvez pas générer une table Rainbow pour un algorithme spécifique avant d'une attaque. Un sel n'est pas censé être secret, vous le stockez à côté du hachage dans votre base de données.
x = hash(salt+password)
Vous le stockerez ensuite dans votre base de données au format salt+x
Cela rendra inutiles les tables Rainbow et les tables de hachage.
Comme d'habitude, ne roulez pas les vôtres, utilisez bcrypt
, scrypt
ou pbkdf2
Qui s'occupe de tous les détails, y compris le salage pour vous. Voir Comment hacher en toute sécurité les mots de passe?
A Rainbow table est une optimisation pour inverser les hachages par force brute. Cela fonctionne par un compromis: vous faites beaucoup de précalcul pour construire une énorme structure de données, et vous pouvez ensuite casser de nombreux hachages rapidement.
Une table Rainbow n'aide que les hachages de fissures dans l'espace de recherche qu'elle recouvre. Concrètement, les tables Rainbow sont conçues pour des textes en clair composés de caractères imprimables et [jusqu'à une certaine longueur. Le principe de base de l'ajout d'un sel est que le texte en clair haché contient à la fois le mot de passe et le sel; avec le sel ajouté, l'espace de recherche devient trop grand pour construire une table Rainbow .
Ainsi, en ajoutant un sel au mot de passe, il n'y a aucun moyen d'amortir le coût d'une attaque par force brute sur de nombreuses fissures. L'attaquant doit faire tout le travail pour chaque hachage, en commençant uniquement lorsqu'il connaît le sel.
Étant donné un hachage et un sel, il n'y a aucun moyen de "retirer le sel". Il s'agit d'une propriété de base d'une fonction de hachage: même si vous savez que deux chaînes sont liées (par exemple, vous savez que le mot de passe est une sous-chaîne de mot de passe + sel), cela ne vous aide pas à trouver le hachage (mot de passe) connaissant le hachage (mot de passe + sel). Il n'est pas nécessaire de cacher le sel à l'attaquant : il doit être unique (et non dérivé du mot de passe ) mais il n'a pas besoin d'être plus secret que le hacher. (Vous pouvez ajouter un sel secret supplémentaire, appelé poivre , mais il n'est utile que dans un ensemble restreint de circonstances.)
Saler le hasch n'est que la moitié de la bataille. Une autre partie du hachage sécurisé des mots de passe est que la fonction de hachage doit être lente, car cela blesse beaucoup plus le pirate que le vérificateur. Ne lancez pas le vôtre , utilisez une méthode qui a été approuvée par des experts. Utilisez bcrypt ou PBKDF2 ou scrypt . La mise en œuvre du stockage de mot de passe ne doit pas impliquer de faire de la cryptographie vous-même, appelez une fonction de bibliothèque.
Pour tout ce que vous vouliez savoir sur le hachage des mots de passe, tout ce que vous ne vouliez pas savoir sur le hachage des mots de passe, et tout ce que vous ne saviez même pas savoir sur le hachage des mots de passe, lisez Comment hacher les mots de passe en toute sécurité? =
Un sel unique résout un problème - chaque compte ne peut pas être attaqué simultanément en une seule tentative de force brute géante.
Supposons que vous ayez essayé de créer une table Rainbow de tous les mots de passe imprimables ASCII de 8 caractères)1. C'est 968 ~ 7,2 millions de milliards (7,2 x 1015) possibilités. Si vous aviez un GPU qui génère des mots de passe à un milliard par seconde, cela prendra environ un mois pour se fissurer (et à 200 W à 0,10 $ par kWh, c'est environ 200 $ en moyenne; ~ 400 $ dans le pire des cas pour votre facture d'électricité).
Vous découvrez donc les hachages de chaque compte sur linkedin à partir d'une sorte d'injection SQL ou de la recherche d'un disque dur avec une ancienne sauvegarde. Vous disposez d'un hachage d'un million d'utilisateurs. Maintenant, si ce sont des hachages non salés, vous pouvez casser la grande majorité de ces hachages en deux mois avec un GPU pour environ 400 $ d'électricité. S'ils sont tous salés de manière unique et que vous voulez en casser tous les millions, cela prendra maintenant 400 millions de dollars d'électricité car chaque sel unique doit avoir sa propre attaque indépendante. Maintenant, avant de dire, je vais construire une plus grande table Rainbow qui inclut les sels, réalisez qu'au moins un sel typique a disons 5 caractères hexadécimaux (16 ** 5) ce qui signifie qu'il faudra un million de fois plus de temps pour créer votre Rainbow (par exemple, vous devrez dépenser 400 millions de dollars en électricité pour la produire).
Ajoutez maintenant le renforcement des clés où au lieu de faire un hachage une fois, vous répétez le processus N fois (par exemple, une fonction de hachage itérée à trois fois serait: hash(salt+hash(salt+hash(salt+pw)))
). Maintenant, au lieu de pouvoir casser un milliard de hachages par seconde, ils peuvent briser un milliard/N de hachages par seconde, donc toutes les attaques seront N fois plus chères. (Un N typique est 5000; donc casser un seul hachage prendrait environ 2 millions de dollars en électricité; le problème avec un N très grand est que ses ressources de calcul plus sur vos serveurs pour vérifier les tentatives de mot de passe).
1 - Ce n'est pas le moyen le plus efficace de casser les mots de passe. Les listes de dictionnaires de millions de mots de passe précédemment utilisés sont beaucoup plus efficaces, car de nombreux mots de passe sont assez faibles. Je ne recommande pas aux gens de générer eux-mêmes des mots de passe (généralement une entropie très faible) ou de réutiliser des mots de passe. Utilisez un service comme keepassx qui vous permet de créer des mots de passe aléatoires pour chaque site et de les stocker dans un fichier crypté. Renforcement des touches + sel unique signifie qu'il est impossible d'essayer de casser tout sauf les hachis les plus simples.
Les tables arc-en-ciel sont des tables de hachage précalculées qui sont utilisées pour casser les mots de passe en un temps relativement plus rapide car la recherche d'une table est beaucoup plus rapide que le calcul d'un hachage.
si l'on peut trouver les mots de passe hachés, on devrait pouvoir trouver les sels correspondants
Le sel connu de l'attaquant ne créera pas de gros problème si l'attaquant tente de casser un mot de passe unique . Le sel rendra difficile et long le déchiffrement d'une liste de mots de passe car pour chaque mot de passe le sel est différent.
Mais où stocke-t-on le sel? Un sel, c'est simplement pour rendre les tables Rainbow "inutiles", non?
Le sel est stocké dans la base de données uniquement et pour chaque mot de passe, vous avez un sel aléatoire différent. Oui, le sel rend très difficile l'utilisation d'une table Rainbow. Les tables Rainbow sont généralement créées à l'aide des mots de passe courants utilisés. L'ajout d'un sel aléatoire rend très difficile d'être fissuré par une table Rainbow.
Un attaquant ne pourrait-il pas simplement construire une table Rainbow, puis convertir tous les hachages et retirer le sel?
Peut-être voulez-vous dire de construire une table arc-en-ciel avec des sels connus (avant de lancer la véritable attaque) parce que vous ne pouvez pas simplement retirer un sel du hachage. Recalculer la table n'est pas recommandé car si vous prenez en compte tous les sels connus, la taille de la table sera trop grande. N'oubliez pas le compromis espace/temps. Si vous créez les tables pour un sel à la fois, vous gaspillez trop d'énergie. L'objectif de la création d'une table Rainbow est de déchiffrer une liste de mots de passe et non un seul mot de passe.
Un autre ajout de valeur très important que le salage apporte deux utilisateurs ne se retrouveront pas avec un hachage de mot de passe identique car les sels seront différents. Imaginez qu'un attaquant soit capable de déchiffrer l'un des mots de passe et si des sels ne sont pas utilisés, l'attaquant n'a qu'à chercher pour savoir quels autres utilisateurs utilisent le même mot de passe.
Premièrement, pourquoi implémentez-vous un code cryptographique de bas niveau pour une page Web? On pourrait penser que c'est un problème résolu: vous utilisez un framework qui utilise des bibliothèques.
Deuxièmement, le hachage protège les mots de passe en cas de fuite des hachages. Votre site ne donne pas accès à la base de données de mots de passe, donc cette situation ne devrait idéalement même pas se produire. Les sels aident à défendre la base de données de mots de passe dans son ensemble dans ce cas.
Si l'attaquant se concentre sur un seul mot de passe de cette base de données, cela ne fait pas beaucoup de différence. Cela rend le travail plus difficile dans le sens où l'attaquant ne peut pas simplement récupérer le mot de passe d'une table Rainbow en recherchant le hachage. Le forçage brutal d'un mot de passe avec un sel n'est que légèrement ralenti car quelques octets supplémentaires sont hachés, ce qui coûte quelques cycles de machine supplémentaires dans les cycles de hachage.
Il était une fois, les systèmes Unix offrant un accès public (tels que les systèmes de campus pour les étudiants) avaient leurs mots de passe fissurés à gauche et à droite. Il y avait plusieurs raisons pour lesquelles cela était facile, mais le problème principal était simple: les informations de hachage de mot de passe sensibles étaient conservées dans le même fichier que les autres champs d'informations sur un utilisateur, et ce fichier, /etc/passwd
était lisible dans le monde entier. Le correctif consiste à placer les informations sensibles dans un fichier séparé, /etc/shadow
. Presto: cela met fin au piratage du mot de passe par les script kiddies qui ont des comptes légitimes sans privilège sur le système.
De même, personne ne sera forcé de forcer vos mots de passe à moins que vous ne les laissiez s'échapper. S'ils fuient et que quelqu'un cherche le mot de passe d'un utilisateur particulier, il n'y a pas grand-chose à faire pour les arrêter.
Les utilisateurs qui utilisent les mêmes mots de passe sur différents systèmes et ne les modifient pas pendant des années et des années seront toujours vulnérables. Vous pouvez le saler, le poivrer et ajouter du ketchup; ne fera aucune différence.
Les sels dissuadent quelqu'un qui veut déchiffrer la base de données de mots de passe dans son ensemble et rassembler autant de mots de passe différents que possible. Les sels signifient que chaque mot de passe doit être forcé par brute individuellement plutôt que simplement récupéré à partir de tables pré-calculées. Si un sel a N bits, alors, au moins idéalement, la base de données de la table Rainbow de l'attaquant doit être 2 ^ N fois plus grande. Un sel de 32 bits signifie que vous avez besoin d'une base de données de table Rainbow quatre milliards de fois plus grande pour simplement rechercher les mots de passe.
Si votre site ne compte que 20 utilisateurs, il n'y a bien sûr que jusqu'à 20 sels différents. Ainsi, un attaquant va prendre le dictionnaire de mots de passe et hacher chaque entrée de 20 manières différentes avec ces sels.
Ainsi, les sels protègent non seulement votre base de données contre la recherche de table Rainbow, mais la protègent également contre le craquage par force brute d'environ un facteur N, où N est le nombre d'utilisateurs. Pour forcer brutalement N mots de passe, l'attaquant doit effectuer N fois le travail en forçant un brut. (En supposant que le sel est suffisamment large: au moins aussi grand que le logarithme de base 2 de N. Si un sel n'a que, disons, 12 bits de large, alors il ne peut y avoir que 4096 sels différents, quel que soit le nombre d'utilisateurs.)
Sans sels, ce n'est pas vrai. Le forçage brutal d'un nombre quelconque de mots de passe en même temps est aussi simple que le forçage brutal, donc plus il y a d'utilisateurs, plus le gain par effort est important.
Il y a quelques facteurs impliqués dans le salage, et vous en manquez (au moins) un.
Ils rendent les tables Rainbow inutiles. Si quelqu'un regarde dans votre base de données de mots de passe et constate qu'un mot de passe est "5f4dcc3b5aa765d61d8327deb882cf99", il n'a même pas besoin de créer une "table arc-en-ciel", il peut simplement rechercher cette valeur sur Google et Google lui dira que c'est le hachage md5 de " mot de passe". Si les mots de passe sont hachés avant d'être mis dans votre base de données, le mécanisme de recherche "Rainbow table" sera inutile. Vous n'avez pas besoin de stocker votre sel dans la base de données pour rendre les tables Rainbow inutiles. Votre sel peut toujours être "xxxx" ou toute autre chaîne arbitraire. Si vous recherchez Google pour 6a316e1fdac8a61d9c7a2ed1cba4a804 (le hachage md5 de "xxxxpassword"), vous n'obtenez pas de résultats.
S'il est fait correctement, le sel signifie généralement qu'un intrus a besoin de les deux votre base de données et votre code afin de casser vos mots de passe. Vous auriez pu hacher votre mot de passe comme "xxxx" + mot de passe ou pw.substring (0,2) + "xxxx" + pw.substring (2). L'attaquant ne sait pas comment vous avez salé vos mots de passe, sauf s'il a également volé votre code. Votre serveur Web ne fonctionne souvent pas sur la même boîte que votre base de données, et avec les langages de programmation compilés, votre code pourrait même ne pas être disponible sur votre serveur Web. Indépendamment des sels que vous stockez dans votre base de données, je recommanderais également d'avoir un long sel fixe arbitraire stocké en dehors de la base de données qui est en outre concaténé au mot de passe avant le hachage.
Les sels uniques rendent le craquage plus cher. Comme quelqu'un d'autre l'a fait remarquer, si vous hachez chaque mot du dictionnaire avec un sel statique ("xxxx"), vous pouvez analyser la base de données de mots de passe entière pour "6a316e1fdac8a61d9c7a2ed1cba4a804" à la recherche de quelqu'un qui est le mot de passe "mot de passe". Si chaque ligne utilise un sel différent, vous devez effectuer N hachages juste pour savoir si l'un des N utilisateurs a le mot de passe "mot de passe".
Sur le deuxième point, attention à n'utiliser qu'un seul sel simple fixe sans aucun autre. Un pirate pourrait essayer de hacher des chaînes arbitraires + "mot de passe" jusqu'à ce qu'il trouve quelqu'un dont le mot de passe était "mot de passe", puis aurait essentiellement craqué votre sel. Dans toute grande base de données de mots de passe, il y a forcément au moins un utilisateur dont le mot de passe est un mot de passe trivial comme "mot de passe".