Stockage du hachage des mots de passe des utilisateurs, par exemple dans une base de données, n'est pas sécurisé car les mots de passe humains sont vulnérables aux attaques par dictionnaire. Tout le monde suggère que cela est atténué par l'utilisation de sels, mais le sel est considéré comme non sensible et n'a pas besoin d'être protégé.
Dans le cas où l'attaquant a le sel, comment son attaque par dictionnaire est-elle devenue plus difficile qu'auparavant? Ne pas avoir accès au sel, en effet, lui enlève-t-il son utilité?
Salt ne vous protège pas contre un attaquant isolé qui ne recherche qu'un seul mot de passe. Un attaquant qui souhaite simplement casser un mot de passe calculera hash(salt + guess)
au lieu de hash(guess)
(si le schéma de mot de passe est hash(salt+password)
).
Salt aide si l'attaquant veut casser de nombreux mots de passe. C'est généralement le cas. Parfois, l'attaquant attaque un site et souhaite pénétrer dans un compte sur ce site, n'importe quel compte. Sans sel, la plupart du travail de l'attaquante peut être utilisée pour tous les comptes, elle peut donc tester chacune de ses tentatives contre tous les comptes à la fois. Avec un sel correctement choisi (c'est-à-dire si deux comptes n'ont pas le même sel), l'attaquant doit recommencer pour chaque mot de passe haché.
De plus, dans un sens, toutes les tentatives de piratage de mot de passe tentent de casser tous les mots de passe des comptes à la fois. C'est parce que les hachages peuvent être précalculés; tout ce qu'il faut, c'est que quelqu'un génère une table de hachage - ou plus efficacement, un table arc-en-ciel - et que le travail initial puisse être distribué à plusieurs attaquants qui peuvent l'utiliser sur n'importe quelle base de données de compte qui utilise le même algorithme de hachage de mot de passe. Encore une fois, le sel rend ces précalculs inutiles.
Une attaque par mot de passe par force brute peut être résumée comme suit:
hash(guess[i]) = hashed_password[j]
.Dans une approche naïve, la deuxième étape nécessite n × p calculs de hachage pour essayer toutes les suppositions contre tous les comptes. Cependant, si la première étape a déjà calculé tous les hachages possibles, la deuxième étape ne nécessite aucun calcul de hachage, testant simplement si chaque hashed_password
est dans la base de données précalculée, donc l'attaque ne nécessite que n recherches de table (cela peut même être accéléré, mais nous sommes déjà passés de n x p calculs lents¹ jusqu'à n recherches de table).
Si chaque mot de passe a un sel différent, pour être utile, le précalcul devrait inclure une entrée pour chaque valeur de sel possible. Si le sel est assez grand, le précalcul est irréalisable. Si le précalcul ne tient pas compte du sel, il ne sera pas utile d'accélérer la deuxième étape, car toute fonction de hachage cryptographique " mixe ”son entrée: connaître le hachage de UIOQWHHXpassword
n'aide pas à calculer le hachage de NUIASZNApassword
. Même pour attaquer un seul compte, l'attaquant doit effectuer p des calculs de hachage pour essayer toutes les suppositions, déjà une amélioration de la recherche de table unique qui serait suffisante si l'attaquant possède un dictionnaire précalculé.
¹ Un mot de passe ne doit pas être stocké sous forme de hachage tel que SHA-1, mais en utilisant une fonction de hachage plus lente telle que bcrypt ou scrypt ou PBKDF2 .
Je vais expliquer chaque niveau de sécurité pour le mot de passe stocké dans la base de données, peut-être que cela aidera à clarifier l'importance du sel.
Niveau 1 : mot de passe stocké en clair dans la base de données.
C'est juste pure stupidité . Mais parfois, les grandes entreprises compromettent leur base de données et, oh surprise, tous les mots de passe sont stockés en clair. C'est dommage!
Niveau 2 : mot de passe stocké à l'aide d'un algorithme de hachage.
Il s'agit d'une étape vers plus de sécurité. Si un attaquant obtient le mot de passe haché, il ne peut toujours pas se connecter à l'aide de ces informations d'identification au service. Il devra d'abord "hacher" le mot de passe en utilisant un Rainbow Table ou par forçage brut it . Cela signifie qu'il faut un peu plus de travail à l'attaquant, mais il peut toujours être possible de récupérer le mot de passe d'origine.
Niveau 3 : mot de passe stocké à l'aide d'un algorithme de hachage avec un sel.
Cela commence à être intéressant. Comme nous l'avons vu sur Niveau 2, un attaquant qui a accès au mot de passe haché peut soit le forcer brutalement, soit utiliser une table Rainbow. L'ajout d'un sel au mot de passe d'origine rend la table Rainbow totalement inutile car ils ne prennent pas en compte le sel. Il est toujours possible d'obtenir la chaîne d'origine à l'aide d'une table Rainbow, mais cela signifierait que dans la table Rainbow, le mot de passe + sel existe. Puisqu'un sel est généralement très long, le impair ayant une valeur hachée d'une chaîne (40+) est presque impossible. La seule solution qui reste est la force brute.
Niveau 4 : mot de passe stocké à l'aide d'un algorithme de hachage avec un sel et un peper.
C'est très intéressant (c'est la raison pour laquelle je poste ma réponse car les vraies sont déjà intéressantes).
Je vous recommande d'utiliser un algorithme de hachage comme BCrypt, SCrypt ou PBKDF2 car ils ne sont pas brisés jusqu'à présent, et sont très lents à pirater, augmentant le temps pour en casser un, puis une base de données complète de mots de passe.
La différence entre le sel et le poivre est leur emplacement. Le sel est généralement stocké dans la base de données mais le poivre se trouve dans le code. Cela peut sembler étrange, mais l'idée originale est qu'une base de données peut être compromise, mais pas le code, laissant à l'attaquant un sel et une liste de mots de passe hachés inutiles. De plus, cela ajoute encore plus de complexité au mot de passe haché, rendant les tables Rainbow complètement inutiles (si nous supposons qu'elles étaient encore un peu utiles avec un sel!) .
Dans le cas où seule la base de données est compromise, même la force brute est alors inutile car l'attaquant ne recherche pas une valeur (le mot de passe d'origine) mais pour deux valeurs (le mot de passe d'origine ET le poivre).
Si vos hachages ne sont pas salés, je peux générer un ensemble de dictionnaires et les stocker dans une base de données (type spécial appelé table Rainbow, c'est plus efficace pour un grand nombre de hachages), alors tout ce que je dois faire est de les rechercher. Fondamentalement, une mémoire géante par rapport à l'optimisation du temps CPU. De plus, si je vois deux utilisateurs avec le même hachage, je sais qu'ils utilisent le même mot de passe.
Un sel rend le hachage de mot de passe de chaque utilisateur unique, et si vous le faites correctement, il sera probablement unique même s'il utilise le même mot de passe sur un autre site (ce qui n'est pas rare), et donc je devrais en fait prendre Word, appliquer du sel et hachez-le, répétez pour la prochaine entrée dans le dictionnaire.
Les hachages non salés sont vulnérables aux attaques de recherche. Il existe des bases de données librement disponibles contenant des millions de hachages de mot de passe (principalement MD5 et SHA1) qui peuvent être utilisées pour rechercher le texte en clair d'un hachage. Ceux-ci peuvent être basés sur des bases de données relationnelles standard ou sur des formats de base de données spécialisés comme les tables Rainbow.
Voici donc un exemple:7c6a61c68ef8b9b6b061b28c348bc1ed7921cb53
(non salé)2d67062d67b4d0eaca31a768e901d04982de7352
(salé avec le préfixe "RxB6aE")
Une recherche rapide sur le premier hachage révélera que le texte en clair est "passw0rd". Cependant, ce dernier est peu susceptible d'être trouvé. Dans le cas où le sel n'est pas connu de l'attaquant, cela rend les attaques par dictionnaire et bruteforce difficiles.
Si vous cherchez à sécuriser les mots de passe dans une base de données, vous devez utiliser quelque chose comme bcrypt. Il utilise un grand nombre d'itérations d'un algorithme de hachage pour ralentir chaque calcul. En tant que tels, les attaques par bruteforce, les attaques par dictionnaire et la construction de tables Rainbow sont hautement irréalisables.