When you sign up for a well-built website, something counterintuitive happens: the site never stores your password. It stores a hash - A fixed-length fingerprint computed from your password - And throws the original away. At your next login it hashes what you type and compares fingerprints. If the site's database later leaks, attackers get hashes, not passwords.
Whether that leak is a shrug or a disaster depends almost entirely on which hash function the developers chose, and how they used it. That's the story of MD5, SHA-256, and bcrypt - Three algorithms often mentioned in the same breath that belong to entirely different eras and jobs.
What makes a hash a hash
Quick summary: a hash is a one-way fingerprint - Easy to compute, impossible to reverse.
A cryptographic hash function takes input of any length and produces a fixed-size output. It makes three promises:
- The same input always yields the same output.
- You can't run it backwards to recover the input.
- You can't find two different inputs that produce the same output (a "collision").
Change one letter of the input, and the output changes beyond recognition.
You can feel this in ten seconds with our in-browser tools. Type password into the MD5 hash generator and you'll get 5f4dcc3b5aa765d61d8327deb882cf99 - Add one exclamation mark and every character changes. Run the same experiments through the SHA-256 generator and you'll see the longer, 64-hex-character fingerprints modern systems use.
Hashing is one-way by design. If a website can email you your old password, it isn't hashing - It's storing your password, and you should treat that site as already breached.
MD5: a museum piece that won't die
MD5, designed by Ron Rivest in 1992, produces a 128-bit digest and was everywhere for a decade. It's now broken in both senses that matter.
First, collisions. Researchers led by Xiaoyun Wang stunned the field in 2004 by generating MD5 collisions. The technique matured until the Flame espionage malware used a forged MD5-based Microsoft certificate in 2012 - A real-world, weaponized collision.
Second, speed. A single modern GPU computes tens of billions of MD5 hashes per second. So even where collisions don't matter, brute force does.
MD5 survives legitimately as a quick checksum for detecting accidental file corruption and for deduplication - Jobs where no adversary is involved. As protection for secrets, it's a chalk outline.
SHA-256: secure, fast - And wrong for passwords
SHA-256, part of the NSA-designed SHA-2 family standardized by NIST in 2001, is a different animal: 256-bit output, no known collisions, no practical attacks. It anchors TLS certificates, code signing, Git's newer object format, and Bitcoin's entire proof-of-work. For data integrity and digital signatures, SHA-256 is the respectable modern default.
So why do security engineers wince when a website stores passwords as SHA-256? Because SHA-256 shares MD5's defining feature: it is fast on purpose. General-purpose hashes are built to fingerprint gigabytes efficiently.
Cracking rigs exploit exactly that. Off-the-shelf GPU hardware tries billions of SHA-256 candidates per second, and password-cracking outfits chain dozens of GPUs together.
Hive Systems' widely cited crack-time tables show short human passwords under fast hashes falling instantly. Combine that speed with humans' predictable choices - See our tour of the most common passwords - And a fast-hashed database is mostly cracked within days of leaking.
History keeps teaching the same lesson. LinkedIn's 2012 breach exposed unsalted fast hashes (SHA-1, MD5's close cousin in speed). When the full dump of 117 million surfaced in 2016, the overwhelming majority were cracked almost immediately.
Fast hash plus human passwords equals plaintext with extra steps. And every cracked password then feeds the reuse attacks described in our credential stuffing explainer.
Salting: one mandatory ingredient
Before slow hashing, one fix is non-negotiable: the salt, a unique random value generated per user and stored alongside the hash. The password is hashed together with its salt, which accomplishes two things:
- Identical passwords produce different hashes. Without salt, every user who chose
123456shares one hash - Crack it once, own them all. - Precomputation dies. Rainbow tables - Gigantic precomputed hash-to-password lookup tables - Become useless, because attackers would need a separate table per salt. Rainbow tables and their history are covered in our guide to how hackers crack passwords.
Salt is not secret, and it doesn't slow an attacker targeting one specific user. It just ensures each user's hash must be attacked individually, from scratch.
bcrypt and Argon2: hashes built to be slow
The real cure inverts the design goal: password hashes should be as slow and expensive as the login experience can tolerate. This family - Key-derivation or password-hashing functions - Includes bcrypt, scrypt, PBKDF2, and Argon2.
bcrypt, designed by Niels Provos and David Mazières in 1999, bakes in salting and a tunable cost factor - Each +1 doubles the work. Tuned so a login takes ~100 milliseconds, a GPU that managed billions of SHA-256 guesses per second manages only thousands of bcrypt guesses.
Argon2 won the Password Hashing Competition in 2015 and adds memory-hardness: each guess demands substantial RAM. That neutralizes the parallelism that makes GPUs and ASICs terrifying.
Current guidance, including NIST SP 800-63B, calls for exactly this class of memory-hard, salted, iterated functions for stored passwords. Argon2id is the modern first choice, and bcrypt is still a solid incumbent.
| MD5 | SHA-256 | bcrypt / Argon2 | |
|---|---|---|---|
| Year introduced | 1992 | 2001 | 1999 / 2015 |
| Output size | 128-bit | 256-bit | 184-bit tag / configurable |
| Collision-resistant today | No - Broken | Yes | Yes |
| Designed speed | Fast | Fast | Deliberately slow, tunable |
| Built-in salt | No | No | Yes |
| GPU guesses per second | Tens of billions | Billions | Thousands |
| Right job | Non-security checksums | Integrity, signatures, blockchains | Stored passwords |
Hashing is not encryption
A common confusion worth killing: hashing and encryption solve opposite problems. Encryption is reversible by whoever holds the key - The right tool when you need the data back, as our plain-English AES-256 explainer covers. Hashing is deliberately irreversible - The right tool when you only ever need to verify a value.
Websites should never be able to decrypt your password, because they should never possess it in recoverable form at all.
What this means for you
You don't control which hash a website uses - LinkedIn's users didn't pick SHA-1. What you control is how expensive your hash is to crack under the worst algorithm you'll ever be stored in:
- Length and randomness dominate. Under bcrypt, a strong password is effectively uncrackable; under leaked MD5, only a long random one survives. Check where yours stands with the password strength checker - It estimates crack times under exactly these scenarios.
- Uniqueness contains the damage. When one site's hashes fall, reused passwords fall everywhere at once.
- Assume eventual leakage. Enable two-factor authentication on important accounts so a cracked hash still isn't enough.
Developers, the checklist is even shorter. Use Argon2id or bcrypt with costs tuned to your hardware. Use per-user random salts - The libraries handle it. And never, ever use a general-purpose hash, however respectable it looks in a benchmark.
FAQ
Can a hash be reversed if the attacker is powerful enough?
Not mathematically - The information simply isn't in the digest, since infinitely many inputs map to each output. What attackers do instead is guess-and-check: hash billions of candidate passwords and compare results. That's why "uncrackable" depends on the password's randomness and the hash's slowness, not on secrecy of the algorithm.
Is SHA-256 broken like MD5?
No. SHA-256 has no known practical collision or preimage attacks, and it remains fully trusted for signatures, certificates, and integrity checking. Its only "flaw" for password storage is efficiency. It was engineered to be fast - And fast is precisely what defenders don't want attackers to have when grinding through password guesses.
What is a rainbow table, in one paragraph?
It's a cleverly compressed precomputed dictionary mapping hashes back to passwords. It lets attackers "reverse" unsalted hashes by lookup instead of brute force. Rainbow tables demolished unsalted MD5 and SHA-1 databases throughout the 2000s. Per-user salts kill the technique completely - Which is why salting has been standard practice for decades, and why its absence in a modern breach is considered negligence.
Why not make bcrypt extremely slow for maximum security?
Because legitimate servers must run the same function on every login. The cost factor is a dial balancing user experience and attacker pain: around 50–250 ms per hash is typical. That asymmetry is enough - A limit of ~10 guesses per second per core turns a cracking campaign that took hours under SHA-256 into centuries.
Do salts need to be kept secret like passwords?
No - Salts are stored in plaintext right next to the hash, and that's fine. Their job isn't secrecy; it's uniqueness, forcing attackers to attack each account separately and making precomputation worthless. A related concept, the "pepper," is a server-side secret added to every hash and kept outside the database, offering an extra layer some high-security systems use.