Skip to content
Data Breaches

Password Hashing and Salting: Correcting Common Architectural Errors

Salting prevents pre-computed attacks but fails to stop real-time cracking if the underlying hashing algorithm lacks deliberate computational resistance.

Illustration: A thick, rusted iron lock sits on a sturdy steel box.
AI-generated illustration: Phish Herald
Quick answer

Salt must be unique per account and stored alongside the hash. It does not encrypt data. Use slow, memory-hard algorithms like Argon2 or bcrypt. Never use MD5 or SHA-1 for credentials. Salt size matters less than uniqueness.

Misreading: Salt is a secret key that must be hidden

Many engineers treat salt like an encryption key, assuming it must be kept secret or stored in a separate, secure location. This is a fundamental error in understanding how verification works. Salt is public data. Its sole purpose is to ensure that two identical passwords produce two different hashes.

If you hide the salt, you cannot verify a user's login. The system must retrieve the salt, combine it with the entered password, and hash the result to compare it with the stored value. Hiding it adds complexity without adding security. An attacker who gains read access to your database will see the salt anyway.

Correct reading: Store the salt in the same database table as the hash. It is often concatenated with the hash or stored in an adjacent column. There is no security benefit to obscuring it. The security comes from the uniqueness of the salt per account, not its secrecy.

Infographic: Password Hashing and Salting: Correcting Common Architectural Errors. Salt is not a secret key and should be stored in plaintext next to the hash. Fast hashing algorithms remain vulnerable to modern hardware regardless of salt length. Global salts provide zero security benefit against l
Infographic: Password Hashing and Salting: Correcting Common Architectural Errors. Free to share with a link to Phish Herald.

Misreading: Longer salts provide more security

A common intuition suggests that a 256-bit salt is vastly superior to a 32-bit salt. While longer salts reduce the probability of collisions, this benefit plateaus quickly. Once the salt is long enough to ensure uniqueness across your user base, adding more bits yields diminishing returns.

The primary goal of salting is to prevent pre-computation. If every account has a unique salt, an attacker cannot build a single rainbow table for your entire database. A 128-bit salt is already statistically unique for billions of users. Increasing this to 512 bits does not stop an attacker from brute-forcing a specific account in real time.

Correct reading: Focus on uniqueness, not length. A random 16-byte (128-bit) salt is sufficient for most systems. Do not waste storage or processing power on excessively long salts. Instead, direct those resources toward using a computationally expensive hashing algorithm.

Misreading: SHA-256 is strong enough for passwords

Engineers often default to SHA-256 or SHA-512 because these are standard cryptographic hashes. This is a dangerous misconception. These algorithms are designed to be fast. Speed is the enemy of password security. Modern GPUs can compute billions of SHA-256 hashes per second.

When an attacker obtains your database, they do not need to reverse the hash. They simply guess common passwords, hash them with the known salt, and compare the result. Fast hashing allows this trial-and-error process to happen at industrial scale. A strong password may take seconds to crack if the underlying hash is too efficient.

Correct reading: Use algorithms specifically designed to be slow and memory-intensive. Argon2, bcrypt, scrypt, and PBKDF2 introduce deliberate computational delays. These algorithms make each guess expensive in terms of time and memory. This slows down attackers to a crawl, even if they have powerful hardware.

Misreading: A global salt protects the database

Some systems use a single "pepper" or global salt applied to all passwords before hashing. This is often confused with per-user salting. A global salt does not prevent rainbow tables if the attacker knows or guesses the salt. More importantly, it does not prevent parallel cracking.

If an attacker targets your database, they can apply the same global salt to billions of guessed passwords and test them against all your users simultaneously. This allows them to crack weak passwords across your entire user base in one pass. Per-user salts force the attacker to run separate cracking jobs for each account.

Correct reading: Use a unique, random salt for every single user account. A global pepper can add a layer of defense in depth, but it does not replace per-user salting. If the pepper is compromised, the entire database becomes vulnerable to parallel attacks. Rely on per-user uniqueness as your primary defense.

Misreading: Hashing encrypts the password

There is a persistent confusion between hashing and encryption. Encryption is reversible; with the correct key, you can recover the original plaintext. Hashing is a one-way function. You cannot recover the password from the hash.

This distinction is critical for system design. You should never store encryption keys for passwords in a way that allows easy decryption. If you encrypt passwords, you are essentially storing them in a reversible format, which increases the risk if the key is leaked. Hashing ensures that even if the database is stolen, the original passwords remain unrecoverable.

Correct reading: Use hashing for credential storage. Use encryption only for data that must be retrieved in its original form, such as credit card numbers or protected health information. Never use encryption for passwords. The system should only know if the provided password matches the stored hash, not what the password actually is.

Misreading: Salting prevents credential stuffing

Salting and hashing protect stored credentials in your database. They do nothing to stop an attacker from using stolen credentials to log in to your live system. Credential stuffing involves automated bots trying username and password pairs from other breaches.

If a user reuses a password, salting cannot save them. The attacker will try the known password, your system will hash it with the user's specific salt, and it will match the stored hash. Salting ensures that a breach of your database does not expose passwords in plaintext, but it does not prevent unauthorized access if the password is already known.

Correct reading: Implement rate limiting, CAPTCHAs, and multi-factor authentication to defend against credential stuffing. Salting is a defensive measure for data at rest. It mitigates the damage of a breach but does not prevent the breach itself. For broader context on external threats, see our guide on third-party data breaches.

Misreading: The hash alone is sufficient

Some developers believe that if they hash a password, they are safe. This ignores the reality of database access controls. If an attacker gains full read access to your database, they obtain the hashes and salts. Without additional protections, they can begin offline cracking immediately.

This is where system-level controls become vital. You must ensure that the database itself is protected from unauthorized access. File integrity monitoring can alert you if critical configuration files are changed, potentially indicating a compromise. Similarly, database activity monitoring can detect unusual queries that might lead to data exfiltration.

Correct reading: Hashing and salting are the last line of defense for credential data. They assume that the attacker has already bypassed perimeter defenses. Combine strong hashing with strict access controls, network segmentation, and monitoring. Remember that full disk encryption protects data at rest on physical drives, but does not help if an attacker has legitimate database access.

Key takeaways

  • Salt is not a secret key and should be stored in plaintext next to the hash.
  • Fast hashing algorithms remain vulnerable to modern hardware regardless of salt length.
  • Global salts provide zero security benefit against large-scale credential stuffing.
Bottom line

Salt must be unique per user and stored openly; the real security comes from using slow, adaptive hashing algorithms like Argon2. Review your current hashing strategy and ensure you can increase the computational cost as hardware capabilities evolve.

Frequently asked questions

Can I use the username as the salt?

No. Usernames are often predictable and not unique enough to prevent parallel attacks. Always use a cryptographically secure random number generator to create unique salts for each account.

How often should I change the salt?

You should not change the salt for an existing account unless you are migrating to a new hashing algorithm. Changing the salt requires re-hashing the password, which can only happen when the user logs in with their current password.

Is MD5 safe if I add a salt?

No. MD5 is broken and extremely fast. Salting prevents pre-computed tables, but it does not stop real-time brute-force attacks. Modern hardware can crack salted MD5 hashes rapidly. Use a dedicated password hashing algorithm instead.

What if I lose the salt?

You cannot recover the password. If the salt is lost or corrupted, you must force a password reset for that user. This highlights the importance of storing the salt reliably alongside the hash.

How this guide was produced: written by the Phish Herald editorial team with AI assistance, checked against the public references listed below, and reviewed when the facts change. See our editorial policy or report an error.

Further reading

  1. IdentityTheft.gov (FTC)
  2. FTC: Data Breach Response, A Guide for Business
  3. Have I Been Pwned
password hashing and saltingpassword hashingsecurity saltingcredential storage

Related stories