Hashing Algorithms Explained
"Just hash the password with SHA-256" is one of the most common mistakes in application security — not because SHA-256 is weak, but because it's fast, and fast is the wrong property for a password hash. Here's the distinction that actually matters, and what's currently recommended instead.
// the split that matters more than the algorithm name
// fast hashes: file integrity, checksums, content addressing
// password hashing needs a KDF, not a hash
A Key Derivation Function adds two things a plain hash doesn't have: deliberate slowness (a tunable work factor) and, for the modern ones, deliberate memory cost — which makes cracking expensive even on specialized hardware (GPUs, ASICs) that laugh at plain SHA-256. Current OWASP Password Storage Cheat Sheet guidance, in order of preference:
// salting — why the same password shouldn't produce the same hash
A salt is random data mixed into the input before hashing, unique per record and stored alongside the hash (it isn't secret). Without one, two users with the password hunter2 get identical hash values, and an attacker can precompute a rainbow table — a lookup of hash → plaintext for common passwords — once, then crack every unsalted database instantly on lookup. Every modern password KDF (bcrypt, scrypt, Argon2) generates and manages a salt automatically as part of its output format; you don't add one manually.
// HMAC — a different tool, often confused with plain hashing
HMAC (Hash-based Message Authentication Code) combines a hash function with a secret key to prove both integrity and authenticity — that a message wasn't altered and that it came from someone who holds the key. A plain SHA-256 hash proves integrity only: anyone can compute a SHA-256 of anything, so a bare hash alongside a message proves nothing about who sent it. This is why webhook signatures, JWT's HS256 algorithm, and API request signing use HMAC-SHA256, not raw SHA-256 — the key is what turns "a hash" into "a hash only the real sender could have produced."
// what "broken" actually means — real collision attacks
// checksums vs cryptographic hashes — not the same category
CRC32 and similar checksums are designed to catch accidental corruption (a flipped bit from a bad network or disk) cheaply — they are not designed to resist someone deliberately engineering a collision, and take microseconds even on huge inputs. Cryptographic hashes (the SHA family) are slower but resist deliberate tampering. Using CRC32 where you need tamper-resistance is a common quiet mistake — it looks the same as a real hash in a hex string, but offers none of the security guarantee.
// try it yourself
Compute MD5, SHA-1, SHA-256, and SHA-512 of any text with the Hash Generator — computed locally via the browser's Web Crypto API, nothing sent to any server.
Every hash function you'll meet falls into one of two categories with opposite design goals. Fast/general-purpose hashes (MD5, SHA-1, SHA-256, SHA-512) are built to process gigabytes per second — perfect for checksums and integrity checks, and exactly wrong for passwords, because an attacker with a stolen hash database can also compute billions of guesses per second. Password KDFs (bcrypt, scrypt, Argon2) are deliberately, tunably slow — that's the entire feature. The same property that makes SHA-256 great at hashing a 2GB file makes it bad at protecting a password.