"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 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.