Tech Deep-DivesJun 27, 2026

Don't Store Passwords with MD5: Hash, Salt, and Password Hashing Explained

MD5 and SHA-256 are hash algorithms, but using them directly for passwords is wrong. This article clarifies hash vs. salt vs. password hashing (bcrypt/Argon2), and why file checksums use SHA-256 while passwords need slow hashes.

"Encrypt passwords with MD5" has two errors: MD5 isn't encryption, and it shouldn't store passwords. Hash, salt, and password hashing are often conflated but solve different problems. Clarifying the three layers shows which to use when—and why file checksums and password storage need opposite algorithms.

Hash one-way, salt, slow password hashing compared

Hash Is Not Encryption—Start There

Hashing is one-way: any input maps to a fixed-length fingerprint; you can't recover the input from the fingerprint. Encryption is two-way: key encrypts and decrypts. "MD5 encryption" is a common misnomer—MD5 is a hash; there's no "decryption."

Two core properties define hash use:

  • Deterministic: same input always yields same output—usable as a fingerprint for verification.
  • Collision-resistant: hard to find two different inputs with the same hash—fingerprints are hard to forge.

General hashes (MD5, SHA-1, SHA-256, SHA-512) add a third trait: optimized for speed. That "fast" helps file checks but is fatal for passwords—see below.

Why Can't General Hashes Store Passwords?

Because they're too fast. Conclusion first: MD5/SHA-256 can run billions of times per second on ordinary hardware—attackers with stolen hashes brute-force or table-lookup common passwords almost instantly.

Two attack patterns:

  • Rainbow tables: precompute hashes of common passwords; lookup stolen hash directly. Hashes are deterministic—123456's SHA-256 is always the same value.
  • Brute / dictionary: modern GPUs do billions of SHA-256 per second; weak passwords fall in seconds.

Speed is a feature elsewhere; for passwords it gives attackers a high-speed guessing target. Password storage needs the opposite—deliberately slow hashing.

Salt: Same Password No Longer Same Hash

Salt fixes "identical passwords → identical hashes." Generate random salt per user, hash salt + password, store salt with the result.

Two direct effects:

  • Rainbow tables fail: tables target bare passwords; random salt changes every hash—no table hit.
  • Can't crack many accounts at once: different salts mean same password hashes differently—attackers must crack one account at a time.

But note: salt stops bulk/table attacks, not "hash is too fast." With one user's salt and hash, attackers still enumerate fast for that account. Fix the algorithm itself for that.

Password Hashing: Deliberately Slow and Memory-Hungry

To counter speed, password hashing algorithms—bcrypt, scrypt, Argon2—are deliberately expensive:

Algorithm Key design Defends against
bcrypt Tunable work factor, exponential iteration growth CPU brute force
scrypt High memory use GPU/ASIC parallelism
Argon2 Tunable time + memory + parallelism Combined GPU/ASIC resistance; modern default

They embed salting and let you tune a cost parameter—single hash takes tens to hundreds of ms. Fine for login; for attackers, thousands of tries per second vs. billions. As hardware improves, raise the cost to maintain difficulty.

When Is SHA-256 the Right Tool?

General hashes aren't obsolete—use them in the right place: fast, stable fingerprints, not password storage.

  • File integrity: compute SHA-256 after download, compare to published value—detect tampering or transfer errors. Speed and determinism are the point.
  • Content addressing / dedup: hash as unique ID (Git objects, CDN cache keys).
  • Digital signature preprocessing: hash then sign to shorten signed data.

In these cases, MD5, SHA-1, SHA-256, SHA-512 on text or files produce comparable fingerprints—the goal is a stable fingerprint, not resisting password brute force. That's where "fast" pays off.

One Table: Which Need, Which Tool

Align layers with scenarios:

Need Use Don't use
Verify file untampered SHA-256
Dedup / unique ID SHA-256, etc. MD5 (collisions broken)
Store user passwords Argon2 / bcrypt / scrypt + salt MD5 / SHA-256 bare hash
Stop rainbow tables / bulk crack Per-user random salt Global fixed salt or none

Simple rule: fast fingerprint → general hash; resist brute force → password hash; stop bulk/table → per-user random salt. Wrong direction (fast hash for passwords, slow hash for large file checksums) is the real mistake.

Summary

Hashing isn't encryption; general hashes (MD5/SHA-256) are built for speed—fine for file checks and dedup, but too fast for passwords—rainbow tables and GPU brute force break them easily. Salt stops same-password-same-hash and bulk attacks but not speed; real password storage uses bcrypt/scrypt/Argon2—deliberately slow and memory-heavy—with tunable cost. Checksum files with SHA-256; store passwords with salted Argon2—don't swap them.

Tools used in this article

Frequently Asked Questions

They shouldn't. MD5/SHA-256 are fast general-purpose hashes—attackers can compute billions per second and use rainbow tables or brute force on common passwords. Store passwords with dedicated password hashing (bcrypt, scrypt, Argon2)—deliberately slow and memory-heavy to make brute force impractical.