La stratégie de base consiste à utiliser une fonction de dérivation de clé pour "hacher" le mot de passe avec un certain sel. Le sel et le résultat du hachage sont stockés dans la base de données. Lorsqu'un utilisateur saisit un mot de passe, le sel et sa saisie sont hachés de la même manière et comparés à la valeur stockée. S'ils correspondent, l'utilisateur est authentifié.
Le diable se cache dans les détails. Tout d'abord, beaucoup de choses dépendent de l'algorithme de hachage choisi. Un algorithme de dérivation de clé tel que le PBKDF2, basé sur un code d'authentification de message à base de hachage, rend "infaisable sur le plan informatique" la recherche d'une entrée (dans ce cas, un mot de passe) qui produira une sortie donnée (ce qu'un attaquant a trouvé dans la base de données).
Une attaque par dictionnaire pré-calculé utilise un index pré-calculé, ou dictionnaire, des sorties de hachage aux mots de passe. Le hachage est lent (ou est censé l'être, en tout cas), donc l'attaquant ne hachera qu'une seule fois tous les mots de passe probables, et stockera le résultat indexé de telle sorte qu'à partir d'un hachage, il puisse rechercher le mot de passe correspondant. Il s'agit d'un compromis classique entre l'espace et le temps. Comme les listes de mots de passe peuvent être énormes, il existe des moyens d'ajuster ce compromis (comme les tables arc-en-ciel), de sorte que l'attaquant puisse renoncer à un peu de vitesse pour gagner beaucoup d'espace.
Les attaques par pré-calcul sont contrecarrées par l'utilisation d'un "sel cryptographique". Il s'agit de données qui sont hachées avec le mot de passe. Ça n'a pas besoin d'être un secret, il suffit qu'il soit imprévisible pour un mot de passe donné. Pour chaque valeur de sel, un attaquant aurait besoin d'un nouveau dictionnaire. Si vous utilisez un octet de sel, un attaquant a besoin de 256 copies de son dictionnaire, chacune générée avec un sel différent. D'abord, il utilise le sel pour trouver le dictionnaire correct, puis il utilise le résultat du hachage pour trouver un mot de passe utilisable. Mais que se passe-t-il si on ajoute 4 octets ? Maintenant, il a besoin de 4 milliards de copies du dictionnaire. En utilisant un sel suffisamment grand, une attaque par dictionnaire est exclue. En pratique, 8 à 16 octets de données provenant d'un générateur de nombres aléatoires de qualité cryptographique constituent un bon sel.
Le précalcul n'étant plus possible, un attaquant doit calculer le hachage à chaque tentative. Le temps nécessaire pour trouver un mot de passe dépend maintenant entièrement du temps nécessaire pour hacher un candidat. Ce temps est augmenté par itération de la fonction de hachage. Le nombre d'itérations est généralement un paramètre de la fonction de dérivation de clé ; aujourd'hui, de nombreux appareils mobiles utilisent 10 000 à 20 000 itérations, tandis qu'un serveur peut en utiliser 100 000 ou plus. (L'algorithme bcrypt utilise le terme "facteur de coût", qui est une mesure logarithmique du temps nécessaire).