Mise à jour: Veuillez noter que je ne demande pas ce qu'est un sel, ce qu'est une table arc-en-ciel, ce qu'est une attaque par dictionnaire ou quel est le but d'un sel. Je demande: si vous connaissez le sel et le hachage des utilisateurs, n'est-il pas assez facile de calculer leur mot de passe?
Je comprends le processus et je le mets moi-même en œuvre dans certains de mes projets.
s = random salt
storedPassword = sha1(password + s)
Dans la base de données que vous stockez:
username | hashed_password | salt
Chaque implémentation de salage que j'ai vue ajoute le sel soit à la fin du mot de passe, soit au début:
hashed_Password = sha1(s + password )
hashed_Password = sha1(password + s)
Par conséquent, une attaque par dictionnaire d'un hacker qui vaut son sel (ha ha) exécuterait simplement chaque mot-clé contre les sels stockés dans les combinaisons courantes énumérées ci-dessus.
Sûrement, la mise en œuvre décrite ci-dessus ajoute simplement une autre étape pour le pirate informatique, sans réellement résoudre le problème sous-jacent? Quelles alternatives existe-t-il pour contourner ce problème, ou est-ce que je comprends mal le problème?
La seule chose que je peux penser à faire est d'avoir un algorithme de mélange secret qui associe le sel et le mot de passe dans un motif aléatoire, ou ajoute d'autres champs utilisateur au processus de hachage, ce qui signifie que le pirate devrait avoir accès à la base de données ET au code pour lacer pour qu’une attaque par dictionnaire se révèle fructueuse. (Mise à jour, comme indiqué dans les commentaires, il est préférable de supposer que le pirate a accès à toutes vos informations, donc ce n'est probablement pas le meilleur).
Permettez-moi de donner un exemple de la façon dont je propose qu'un pirate pirate une base de données utilisateur avec une liste de mots de passe et de hachages:
Données de notre base de données piratée:
RawPassword (not stored) | Hashed | Salt
--------------------------------------------------------
letmein WEFLS... WEFOJFOFO...
Dictionnaire de mots de passe commun:
Common Password
--------------
letmein
12345
...
Pour chaque enregistrement utilisateur, bouclez les mots de passe communs et hachez-les:
for each user in hacked_DB
salt = users_salt
hashed_pw = users_hashed_password
for each common_password
testhash = sha1(common_password + salt)
if testhash = hashed_pw then
//Match! Users password = common_password
//Lets visit the webpage and login now.
end if
next
next
J'espère que cela illustre beaucoup mieux mon propos.
Compte tenu de 10 000 mots de passe courants et de 10 000 enregistrements d'utilisateurs, nous aurions besoin de calculer 100 000 000 de hachages pour découvrir autant de mots de passe d'utilisateurs que possible. Cela peut prendre quelques heures, mais ce n'est pas vraiment un problème.
Mise à jour sur la théorie du craquage
Nous supposerons que nous sommes un hébergeur corrompu, qui a accès à une base de données de hachages et de sels SHA1, avec votre algorithme pour les mélanger. La base de données contient 10 000 enregistrements d'utilisateurs.
Ce site prétend pouvoir calculer 2 300 000 000 de hachages SHA1 par seconde en utilisant le GPU. (Dans la situation du monde réel, ce sera probablement plus lent, mais pour l'instant, nous utiliserons ce chiffre cité).
(((95 ^ 4) / 2300000000) / 2) * 10000 = 177 secondes
Étant donné une gamme complète de 95 caractères ASCII imprimables, avec une longueur maximale de 4 caractères, divisée par le taux de calcul (variable), divisé par 2 (en supposant que le temps moyen pour découvrir le mot de passe nécessitera en moyenne 50% de permutations) pour 10000 utilisateurs, il faudrait 177 secondes pour déterminer tous les mots de passe des utilisateurs dont la longueur est <= 4.
Ajustez un peu pour le réalisme.
(((36 ^ 7) / 1000000000) / 2) * 10000 = 2 jours
En supposant la non-sensibilité à la casse, avec une longueur de mot de passe <= 7, uniquement des caractères alphanumériques, il faudrait 4 jours pour résoudre 10000 enregistrements d'utilisateurs, et j'ai réduit de moitié la vitesse de l'algorithme pour refléter les frais généraux et les circonstances non idéales.
Il est important de reconnaître qu'il s'agit d'une attaque par force brute linéaire, tous les calculs sont indépendants les uns des autres, c'est donc une tâche parfaite pour plusieurs systèmes à résoudre. (IE facile à configurer 2 ordinateurs exécutant une attaque de différentes extrémités qui réduiraient la moitié du temps d'exécution).
Étant donné le cas du hachage récursif d'un mot de passe 1000 fois pour rendre cette tâche plus coûteuse en calcul:
(((36 ^ 7) / 1 000 000 000) / 2) * 1000 secondes = 10,8839117 heures
Cela représente une longueur maximale de 7 caractères alphanumériques, à une vitesse d'exécution inférieure à la moitié de la valeur citée pour un utilisateur .
Le hachage récursif 1 000 fois bloque efficacement une attaque globale, mais les attaques ciblées sur les données des utilisateurs restent vulnérables.
la source
Réponses:
Oui, vous n'avez besoin que de 3 jours pour sha1 (sel | mot de passe). C'est pourquoi de bons algorithmes de stockage de mots de passe utilisent un hachage de 1000 itérations: il vous faudra 8 ans.
la source
Cela n'arrête pas les attaques par dictionnaire.
Cela empêche quelqu'un qui parvient à obtenir une copie de votre fichier de mot de passe d'utiliser une table arc-en-ciel en pour déterminer quels sont les mots de passe à partir des hachages.
Finalement, cela peut être forcé brutalement. La réponse à cette partie est de forcer vos utilisateurs à ne pas utiliser les mots du dictionnaire comme mots de passe (exigences minimales d'au moins un chiffre ou caractère spécial, par exemple).
Mise à jour :
J'aurais dû le mentionner plus tôt, mais certains (la plupart?) Systèmes de mot de passe utilisent un sel différent pour chaque mot de passe, probablement stocké avec le mot de passe lui-même. Cela rend inutile une seule table arc-en-ciel. C'est ainsi que la crypte UNIX bibliothèque de , et les systèmes d'exploitation modernes de type UNIX ont étendu cette bibliothèque avec de nouveaux algorithmes de hachage.
Je sais pertinemment que la prise en charge de SHA-256 et SHA-512 a été ajoutée dans les nouvelles versions de GNU crypt.
la source
Pour être plus précis, une attaque par dictionnaire , c'est-à-dire une attaque où tous les mots d'une liste exhaustive sont essayés, n'est pas "impossible", mais elle devient irréalisable : chaque bit de sel double la quantité de stockage et de calcul nécessaires .
Ceci est différent des attaques de dictionnaire pré-calculées comme les attaques impliquant des tables arc-en-ciel où peu importe que le sel soit secret ou non.
Exemple: Avec un salt 64 bits (soit 8 octets), vous devez vérifier 2 64 combinaisons de mots de passe supplémentaires dans votre attaque par dictionnaire. Avec un dictionnaire de 200 000 mots, vous devrez faire
tests dans le pire des cas - au lieu de 200 000 tests sans sel.
Un autre avantage de l'utilisation de salt est qu'un attaquant ne peut pas pré-calculer les hachages de mot de passe à partir de son dictionnaire. Cela prendrait simplement trop de temps et / ou d'espace.
Mise à jour
Votre mise à jour suppose qu'un attaquant connaît déjà le sel (ou l'a volé). C'est bien sûr une situation différente. Il n'est toujours pas possible pour l'attaquant d'utiliser une table arc-en-ciel précalculée. Ce qui compte beaucoup ici, c'est la vitesse de la fonction de hachage. Pour rendre une attaque impraticable, la fonction de hachage doit être lente. MD5 ou SHA ne sont pas de bons candidats ici car ils sont conçus pour être rapides, de meilleurs candidats pour les algorithmes de hachage sont Blowfish ou certaines de ses variantes.
Mise à jour 2
Une bonne lecture sur la question de la sécurisation de vos hachages de mots de passe en général (allant bien au-delà de la question d'origine mais toujours intéressante):
Corollaire de l'article: Utilisez des hachages salés créés avec bcrypt (basé sur Blowfish) ou Eksblowfish qui vous permet d'utiliser un temps de configuration configurable pour ralentir le hachage.
la source
Un dictionnaire est une structure où les valeurs sont indexées par des clés. Dans le cas d'une attaque par dictionnaire pré-calculée, chaque clé est un hachage, et la valeur correspondante est un mot de passe qui entraîne le hachage. Avec un dictionnaire pré-calculé en main, un attaquant peut «instantanément» rechercher un mot de passe qui produira le hachage nécessaire pour se connecter.
Avec le sel, l'espace requis pour stocker le dictionnaire augmente rapidement… si rapidement que tenter de précalculer un dictionnaire de mots de passe devient vite inutile.
Les meilleurs sels sont choisis au hasard dans un générateur de nombres aléatoires cryptographiques. Huit octets est une taille pratique, et plus de 16 octets ne sert à rien.
Le sel fait bien plus que simplement «rendre le travail d'un agresseur plus irritant». Il élimine toute une classe d'attaque: l'utilisation de dictionnaires précalculés.
Un autre élément est nécessaire pour sécuriser complètement les mots de passe, c'est le «renforcement des clés». Un tour de SHA-1 n'est pas assez bon: un algorithme de hachage de mot de passe sûr devrait être très lent en calcul.
De nombreuses personnes utilisent PBKDF2, une fonction de dérivation de clé, qui renvoie les résultats à la fonction de hachage des milliers de fois. L'algorithme "bcrypt" est similaire, utilisant une dérivation itérative de clé qui est lente.
Lorsque l'opération de hachage est très lente, une table précalculée devient de plus en plus souhaitable pour un attaquant. Mais le sel approprié va à l'encontre de cette approche.
commentaires
Voici les commentaires que j'ai faits sur la question.
Sans sel, un attaquant n'utiliserait pas la méthode démontrée dans "Update 2". Il ferait simplement une recherche dans une table pré-calculée et obtiendrait le mot de passe en temps O (1) ou O (log n) (n étant le nombre de mots de passe candidats). Le sel est ce qui empêche cela et l'oblige à utiliser l'approche O (n) montrée dans "Update 2".
Une fois réduit à une attaque O (n), nous devons considérer le temps que prend chaque tentative. Le renforcement des clés peut faire en sorte que chaque tentative dans la boucle dure une seconde complète, ce qui signifie que le temps nécessaire pour tester 10 000 mots de passe sur 10 000 utilisateurs passera de 3 jours à 3 ans. … et avec seulement 10 000 mots de passe, vous risquez d'en casser zéro. mots de passe à cette époque.
Vous devez considérer qu'un attaquant va utiliser les outils les plus rapides qu'il peut, pas PHP, donc des milliers d'itérations, plutôt que 100, seraient un bon paramètre pour le renforcement des clés. Le calcul du hachage d'un seul mot de passe devrait prendre une grande fraction de seconde.
Le renforcement de clé fait partie des algorithmes standard de dérivation de clé PBKDF1 et PBKDF2, de PKCS # 5, qui font d'excellents algorithmes d'obfuscation de mot de passe (la «clé dérivée» est le «hachage»).
De nombreux utilisateurs de StackOverflow se réfèrent à cet article car il s'agissait d'une réponse à l'article de Jeff Atwood sur les dangers des tables arc-en-ciel. Ce n'est pas mon article préféré, mais il aborde ces concepts plus en détail.
Bien sûr, vous supposez que l'attaquant a tout: sel, hachage, nom d'utilisateur. Supposons que l'attaquant est un employé corrompu de la société d'hébergement qui a vidé la table des utilisateurs sur votre site de fans myprettypony.com. Il essaie de récupérer ces mots de passe parce qu'il va se retourner et voir si vos fans de poney ont utilisé le même mot de passe sur leurs comptes citibank.com.
Avec un schéma de mot de passe bien conçu, il sera impossible pour ce type de récupérer des mots de passe.
la source
L'intérêt du salage est d'éviter l'amortissement de l'effort de l'attaquant.
Sans sel, une seule table d'entrées de mot de passe de hachage précalculées (par exemple MD5 de toutes les chaînes alphanumériques de 5 caractères, facile à trouver en ligne) peut être utilisée sur chaque utilisateur de chaque base de données dans le monde.
Avec un sel spécifique au site, l'attaquant doit calculer lui-même la table et peut ensuite l'utiliser sur tous les utilisateurs du site.
Avec un sel par utilisateur, l'attaquant doit déployer cet effort pour chaque utilisateur séparément.
Bien sûr, cela ne fait pas grand-chose pour protéger les mots de passe vraiment faibles tout droit sortis d'un dictionnaire, mais cela protège les mots de passe raisonnablement forts contre cet amortissement.
la source
De plus - un autre point important - l'utilisation d'un sel spécifique à l'UTILISATEUR empêche la détection de deux utilisateurs avec le MÊME mot de passe - leurs hachages correspondent. C'est pourquoi le hachage est souvent un hachage (sel + nom d'utilisateur + mot de passe)
Si vous essayez de garder le hachage secret, l'attaquant ne peut pas non plus vérifier les hachages.
Edit- vient de remarquer que le point principal a été fait dans un commentaire ci-dessus.
la source
Les sels sont mis en œuvre pour empêcher les attaques de table arc-en-ciel. Une table arc-en-ciel est une liste de hachages pré-calculés, ce qui rend la traduction d'un hachage en sa phrase beaucoup plus simple. Vous devez comprendre que le salage n'est pas efficace en tant que prévention moderne pour déchiffrer un mot de passe à moins que nous ayons un algorithme de hachage moderne.
Alors disons que nous travaillons avec SHA1, profitons des récents exploits découverts avec cet algo, et disons que nous avons un ordinateur fonctionnant à 1000000 hachages / seconde, il faudrait 5,3 millions de millions d'années pour trouver une collision , alors oui php peut travailler 300 par seconde, gros woop, n'a pas vraiment d'importance. La raison pour laquelle nous salons est que si quelqu'un a pris la peine de générer toutes les expressions courantes du dictionnaire, (2 ^ 160 personnes, bienvenue dans les exploits de l'ère 2007).
Voici donc une base de données réelle, avec 2 utilisateurs que j'utilise à des fins de test et d'administration.
En fait, le schéma de salage est votre sha1 (heure d'enregistrement + nom d'utilisateur). Allez-y, dites-moi mon mot de passe, ce sont de vrais mots de passe en production. Vous pouvez même vous asseoir là et hacher une liste de mots en php. Devenir fou.
Je ne suis pas fou, je sais juste que c'est sûr. Pour le plaisir, le mot de passe du test est
test
.sha1(sha1(1281546174.065087 + test) + test) = 5872548f2abfef8cb729cac14bc979462798d023
Vous auriez besoin de générer une table arc-en-ciel entière avec
27662aee8eee1cb5ab4917b09bdba31d091ab732
pour seul cet utilisateur. Cela signifie que je peux réellement permettre que mes mots de passe ne soient pas tous compromis par une seule table arc-en-ciel, le hacker doit générer une table arc-en-ciel entière pour 27662aee8eee1cb5ab4917b09bdba31d091ab732 pour le test, et encore f3f7735311217529f2e020468004a2af5b3de7. Pensez aux 5,3 millions de millions d'années pour tous les hachages. Pensez à la taille du stockage des 2 ^ 80 hachages (c'est bien plus de 20 yottaoctets ), cela n'arrivera pas.Ne confondez pas le salage comme un moyen de créer un hachage que vous ne pouvez jamais décoder, c'est un moyen d'empêcher une table arc-en-ciel de traduire tous vos mots de passe utilisateur. C'est impossible à ce niveau de technologie.
la source
L'idée derrière l'attaque par dictionnaire est que vous prenez un hachage et trouvez le mot de passe, à partir duquel ce hachage a été calculé, sans calcul de hachage. Maintenant, faites de même avec un mot de passe salé - vous ne pouvez pas.
Ne pas utiliser de sel rend la recherche de mot de passe aussi simple que la recherche dans la base de données. L'ajout d'un sel oblige l'attaquant à effectuer un calcul de hachage de tous les mots de passe possibles (même pour l'attachement de dictionnaire, cela augmente considérablement le temps d'attaque).
la source
En termes simples: sans salage, chaque mot de passe candidat n'a besoin d'être haché qu'une seule fois pour le vérifier auprès de chaque utilisateur, n'importe où dans «l'univers connu» (collection de bases de données compromises), dont le mot de passe est haché via le même algorithme. Avec le salage, si le nombre de valeurs possibles de sel dépasse sensiblement le nombre d'utilisateurs dans «l'univers connu», chaque mot de passe candidat doit être haché séparément pour chaque utilisateur contre lequel il sera testé.
la source
En termes simples, le salage n'empêche pas un hachage d'attaquer (force brute ou dictionnaire), il ne fait que le rendre plus difficile; l'attaquant devra soit trouver l'algorithme de salage (qui, s'il est mis en œuvre correctement, utilisera plus d'itérations) ou brutforce l'algo, qui, à moins d'être très simple, est presque impossible. Le salage élimine également presque complètement l'option de recherche de table arc-en-ciel ...
la source
Le sel fait la table Rainbow attaques de beaucoup plus difficiles car il rend un hachage de mot de passe beaucoup plus difficile à déchiffrer. Imaginez que vous ayez un horrible mot de passe du numéro 1. Une attaque de table arc-en-ciel le casserait immédiatement.
Imaginez maintenant que chaque mot de passe dans la base de données soit salé avec une longue valeur aléatoire de nombreux caractères aléatoires. Maintenant, votre mauvais mot de passe de "1" est stocké dans la base de données sous la forme d'un hachage de 1 plus un tas de caractères aléatoires (le sel), donc dans cet exemple, la table arc-en-ciel doit avoir le hachage pour quelque chose comme: 1.
Donc, en supposant que votre sel est quelque chose de sécurisé et aléatoire, disons ()% ISLDGHASKLU ( % #% #, la table arc-en-ciel du hacker devrait avoir une entrée pour 1 * ()% ISLDGHASKLU (*% #% #. Utilisant maintenant une table arc-en-ciel même ce simple mot de passe n'est plus pratique.
la source