A salt is a random value added to a password before hashing. It makes identical passwords produce different hash values, preventing attackers from matching every stolen hash against one lookup table of precomputed results. section 3.9 section 8.12
Use salts defensively by following these practices:
- Generate a new salt for each password rather than reusing one standard salt. section 3.9
- Store each salt alongside its password hash; the salt does not need to be secret. section 8.12
- Pair salting with a modern password-hashing function such as bcrypt, SHA-2, or SHA-3; salting does not replace a strong function. section 8.12
- Consider peppering as an additional defense by keeping a shared secret in configuration outside the database. section 8.12
Why a salt changes the attack
Without salts, an attacker can compare stolen hashes with a precomputed list of common password hashes. With a different salt for every password, the attacker must calculate separate guesses for each salt, greatly increasing the work required. section 3.9 section 8.12
require 'bcrypt' def hash_password(password) salt = BCrypt::Engine.generate_salt pepper = ENV['PEPPER'] hashed_password = BCrypt::Engine.hash_secret( pepper + password + salt, salt) return [hashed_password, salt] end def check_password(password, hashed_password, salt) pepper = ENV['PEPPER'] recalculated_hash = BCrypt::Engine.hash_secret( pepper + password + salt, salt) return hashed_password == recalculated_hash end
Shows bcrypt functions that generate a salt, combine password, salt, and pepper, store the result, and recalculate it during verification. section 8.12




