Salting
In short
Salting is the practice of adding a unique random value to each password before hashing it, so identical passwords produce different hashes and resist cracking.
What is salting?
A salt is a random string, typically 16 bytes or more, generated separately for every password. Before the password is hashed, the salt is combined with it, and the salt is stored next to the resulting hash in the database. When the user logs in, the server takes the stored salt, combines it with the password they typed, hashes the result, and compares it with the stored hash.
Salting defeats two shortcuts attackers use after stealing a password database. Without salts, everyone who chose password123 has the same hash, so cracking one cracks them all, and attackers can use rainbow tables, huge precomputed lists of hashes for common passwords, to look up passwords instantly. With a unique salt per user, every hash is different and every password must be attacked separately.
Think of the salt as a unique seasoning added to each dish: two cooks can start with the same ingredients, but the finished dishes taste different, so tasting one tells you nothing about the other. The salt is not a secret and does not need to be hidden; its only job is to make each hash unique.
Salting is often confused with peppering, which adds a single secret value kept outside the database, such as in a secrets manager, as an extra layer. In practice you rarely salt by hand, because password-hashing algorithms such as Argon2id, bcrypt, and scrypt generate a salt automatically and store it inside the hash string. Salting alone is not enough, since fast hashes like SHA-256 can still be brute-forced quickly, so always pair it with one of these deliberately slow algorithms.
Key takeaways
- A salt is a unique random value added to each password before hashing.
- Salts make identical passwords produce different hashes.
- Salting defeats rainbow tables and forces attackers to crack each hash separately.
- Salts are stored with the hash and do not need to be secret.
- Argon2id, bcrypt, and scrypt handle salting automatically.
Example
import { randomBytes, scryptSync, timingSafeEqual } from "node:crypto";
// Manual salting shown for clarity; bcrypt and Argon2 libraries do this for you
// Registration: a new random salt for every password
const salt = randomBytes(16).toString("hex");
const hash = scryptSync(password, salt, 64).toString("hex");
await db.users.save({ email, salt, hash }); // the salt is stored, not secret
// Login: repeat the hash with the stored salt and compare in constant time
const attempt = scryptSync(loginPassword, user.salt, 64);
const ok = timingSafeEqual(attempt, Buffer.from(user.hash, "hex"));Readers ask
Does a salt need to be secret?
No. A salt is stored in plain form next to the hash, because the server needs it to check logins. Its purpose is to make every hash unique, not to hide information.
What is the difference between a salt and a pepper?
A salt is unique per password and stored with the hash in the database. A pepper is a single secret value shared by all passwords and kept outside the database, so a stolen database alone is not enough to start cracking.
Does bcrypt use a salt?
Yes. bcrypt generates a random salt automatically and embeds it in the hash string it returns, so you store only that one string. Most Argon2id libraries work the same way.
See also
- HashingSecurity, p. 14Hashing is the process of turning any input into a fixed-length value with a one-way function, used to verify data integrity and store passwords safely.
- AuthenticationSecurity, p. 2Authentication is the process of verifying that a user, device, or service really is who it claims to be, for example by checking a password or passkey.
- EncryptionSecurity, p. 12Encryption is the process of scrambling data with a key so that only someone holding the correct key can turn it back into its original, readable form.
- DatabaseDatabases, p. 6A database is an organized collection of data stored on a computer, managed by software that lets applications save, search, and update it efficiently.
Spotted a mistake or something missing on this page?Suggest an edit