Password hashing and salting protects user passwords by storing a one-way derived value instead of the original password. This cheat sheet covers how secure password storage works, why ordinary fast hashes are not enough, and how salts, peppers, and key derivation functions reduce attack risk. College students need these ideas for secure software design, authentication systems, and defensive database handling.
Key Facts
- A password should be stored as hash = KDF(password, salt, work_factor), not as plaintext or as a simple unsalted hash.
- A salt must be unique per password record and should be generated with a cryptographically secure random number generator, commonly at least 128 bits.
- A pepper is a secret value stored outside the password database, so it can add protection if only the database is stolen.
- Password verification recomputes candidate_hash = KDF(input_password, stored_salt, stored_work_factor) and compares it to the stored hash.
- Use a constant-time comparison function for password hash checks to reduce timing side-channel leaks.
- Fast general-purpose hashes such as MD5, SHA-1, and raw SHA-256 are not suitable for password storage because attackers can test guesses extremely quickly.
- Recommended password hashing algorithms include Argon2id, bcrypt, scrypt, and PBKDF2 when configured with current security parameters.
- Work factors should be increased over time so each password check remains intentionally expensive enough to slow offline guessing attacks.
Vocabulary
- Hash function
- A function that maps input data to a fixed-size output in a way that is easy to compute but hard to reverse.
- Password hashing
- The process of transforming a password into a stored one-way value using a password-specific algorithm or key derivation function.
- Salt
- A random, non-secret value stored with a password hash to make identical passwords produce different stored results.
- Pepper
- A secret value added during password hashing that is stored separately from the password database.
- Key derivation function
- An algorithm such as Argon2id, bcrypt, scrypt, or PBKDF2 that deliberately makes password guessing slower and more costly.
- Work factor
- A configuration value that controls how much time, memory, or computation the password hashing algorithm requires.
Common Mistakes to Avoid
- Storing plaintext passwords is wrong because a database leak immediately exposes every user password with no cracking required.
- Using the same salt for all users is wrong because attackers can reuse computations across many accounts instead of attacking each record separately.
- Using MD5, SHA-1, or a single SHA-256 hash for passwords is wrong because these fast hashes allow billions of guesses per second on modern hardware.
- Treating the salt as a secret is wrong because salts are meant to be stored with the hash; secrecy should come from the password, algorithm cost, and any separate pepper.
- Lowering the work factor for convenience is risky because it makes offline guessing cheaper for attackers after a database breach.
Practice Questions
- 1 A system stores 1,000,000 password records and uses a 128-bit random salt for each record. How many possible salt values exist, and why is this enough to make accidental salt reuse extremely unlikely?
- 2 If an attacker can test 50,000 guesses per second against a weak password hash, about how many guesses can the attacker test in one hour?
- 3 Write pseudocode for registering a password using a secure random salt, Argon2id, a stored work factor, and a record containing algorithm, salt, work factor, and hash.
- 4 Explain why two users with the same password should still have different stored password records, and describe what role the salt plays in that result.
Understanding Password Hashing and Salting Reference
Password storage is mainly about limiting damage after a breach. An attacker who steals a login database can work offline. They do not need to keep sending requests to the website, so rate limits and account lockouts no longer slow them down.
They can try huge lists of common passwords, leaked passwords, names, dates, and likely variations. A deliberately slow password derivation process makes every guess cost more time and hardware resources.
Memory use matters too. Algorithms that require substantial memory make large scale cracking less efficient on graphics processors and specialised hardware.
Salts solve a specific problem with repeated passwords. Without separate random salts, two users who choose the same password would have matching stored values. Attackers could spot those matches immediately.
They could prepare a lookup table before stealing any database, then reuse it against many victims. A unique salt means the same password produces different derived values in different records. The salt is not meant to be hidden.
It can sit beside the derived value in the database because its job is uniqueness, not secrecy. Randomness is important because predictable values such as usernames or record numbers can weaken this protection.
A pepper has a different role. It is a secret shared by the application or a dedicated secret management service. If a database backup leaks but the pepper does not, the attacker has one more important barrier before checking password guesses.
This does not make weak passwords safe, and it does not help if the application server is fully compromised. It should be protected like a high value key, with restricted access and a rotation plan. Teams must think carefully about rotation because changing a pepper may require users to log in again or may require support for an old pepper during a controlled migration.
Secure verification needs careful engineering beyond choosing a named algorithm. The system should save enough information with each record to verify it later, including the algorithm version and the settings used at creation time. This allows gradual upgrades.
When a user successfully logs in with an older setting, the server can derive a new value using stronger current settings and replace the old record. The chosen cost must be tested on real servers under normal traffic.
A cost that is too low helps attackers, while a cost that is too high can slow legitimate logins or create denial of service risks. Developers should use trusted library functions, avoid writing cryptography from scratch, compare results in constant time, protect password reset routes, and never write passwords to logs, error reports, analytics tools, or backups.