Qu'est-ce qu'un salt en cryptographie ?
Le salt est une donnée aléatoire ajoutée à un mot de passe avant hachage. Il empêche les rainbow tables et masque les mots de passe identiques.
Un salt (« sel » en français) est une donnée aléatoire ajoutée à un mot de passe avant son hachage. Sans salt, le hachage d'un mot de passe est vulnérable aux rainbow tables et trahit les utilisateurs qui ont choisi le même mot de passe. Définition pratique.
Le problème sans salt
Imaginez une base de données qui stocke SHA-256(motdepasse) directement. Trois problèmes :
- Rainbow tables — un attaquant a précalculé les hashes de 10 milliards de mots de passe courants. Il compare votre hash à sa table : si match, il a le mot de passe en clair.
- Mots de passe identiques visibles — deux utilisateurs avec le mot de passe
azerty123auront le même hash en base. L'attaquant repère instantanément les comptes les plus faibles. - Crackage groupé — un seul cassage permet de récupérer tous les comptes utilisant ce mot de passe.
La solution : ajouter un salt aléatoire
On stocke hash(motdepasse + salt) avec le salt à côté (en clair, pas un secret). Chaque utilisateur a son propre salt aléatoire.
// Pseudo-code
salt = aleatoire(16 octets)
hash = bcrypt(motdepasse + salt, cost=12)
base.insert(utilisateur, salt, hash)
Conséquences :
- Les rainbow tables deviennent inutilisables : pour chaque salt possible, l'attaquant devrait recalculer toute la table.
- Deux utilisateurs avec le même mot de passe ont des hashes différents.
- L'attaquant doit casser chaque mot de passe individuellement.
Générer un salt cryptographique aléatoire
Taille recommandée d'un salt
Le salt doit être suffisamment long pour qu'aucune rainbow table par salt ne soit calculable :
- Minimum : 8 octets (64 bits).
- Recommandé OWASP 2026 : 16 octets (128 bits).
- Bcrypt : impose 16 octets encodés en base64 (22 caractères).
- Argon2 : 16 octets minimum, peut aller jusqu'à 64.
Salt vs pepper
Le pepper est un second secret ajouté identique pour tous les utilisateurs et stocké séparément de la base (variable d'environnement, HSM, vault).
| Salt | Pepper | |
|---|---|---|
| Unique par utilisateur | ✅ | ❌ (commun à tous) |
| Stocké à côté du hash | ✅ | ❌ (hors base) |
| Secret | Non | Oui |
| Protège contre fuite de la base | ✅ | ✅✅ (double couche) |
| Protège contre rainbow tables | ✅ | ✅ |
Le pepper protège même si la base entière est volée, à condition que le pepper lui-même n'ait pas été extrait. Souvent utilisé en complément du salt pour les comptes très sensibles.
Erreurs courantes
- Salt non aléatoire — utiliser l'ID utilisateur, l'email ou la date d'inscription comme salt. Insuffisant : prévisible.
- Salt réutilisé — un seul salt pour toute la base. Annule l'effet anti-rainbow-table.
- Salt trop court — 4 octets (32 bits) permettent de générer des rainbow tables par salt en quelques jours.
- Concatenation naïve —
md5(motdepasse + salt). Vulnérable aux length-extension attacks sur MD5/SHA-1. Toujours utiliser un algorithme prévu pour le salage (bcrypt, Argon2).
Comment générer un salt
Toujours via un PRNG cryptographique :
- JavaScript :
crypto.getRandomValues(new Uint8Array(16)) - Python :
os.urandom(16)ousecrets.token_bytes(16) - Node.js :
crypto.randomBytes(16) - Rust :
rand::thread_rng().fill_bytes(&mut salt) - Convertly : Générateur de salt en ligne (16 octets en base64)