Hashing is one of the most misunderstood topics in practical software security. The same word — "hashing" — covers two completely different use cases: verifying that data has not changed (integrity), and safely storing passwords so that a database breach does not expose user credentials. The algorithms suited to these two jobs are fundamentally different. Using the wrong one in the wrong context is a critical security mistake that has caused some of the most damaging breaches in recent history.
Overview
A cryptographic hash function takes an arbitrary-length input and produces a fixed-length output (the digest). The function is one-way: given the digest, you cannot recover the original input without brute-force. It is deterministic: the same input always produces the same output. And it has the avalanche effect: a single-bit change in input produces a completely different output.
MD5, SHA-256, and bcrypt are all hash functions, but they serve different masters:
- MD5 (1991) — designed for speed. Cryptographically broken. Output: 128 bits.
- SHA-256 (2001, NIST) — designed for integrity and signatures. Secure but too fast for passwords. Output: 256 bits.
- bcrypt (1999) — designed specifically for passwords. Intentionally slow, self-salting. Output: 60-char encoded string.
Generate hashes with the Hash Generator to see the output format for each algorithm.
Side-by-Side Comparison
| Parameter | MD5 | SHA-256 | bcrypt |
|---|---|---|---|
| Output length | 128 bits (32 hex characters) | 256 bits (64 hex characters) | 60-character encoded string (includes salt + cost) |
| Speed | Extremely fast (~10 billion hashes/sec on GPU) | Fast (~1 billion hashes/sec on GPU) | Intentionally slow (~10,000 hashes/sec at cost 12) |
| Collision resistance | Broken — collisions demonstrated since 2004 | Strong — no known collisions | Not applicable (non-deterministic; designed for uniqueness) |
| Salting | No built-in (must be added manually) | No built-in (must be added manually) | Built-in — random 128-bit salt per hash |
| Reversible | No — but GPU brute-force and rainbow tables make it trivial | No — computationally infeasible for strong passwords | No — slow per-attempt cost defeats GPU attacks |
| Use for passwords | Never | Never | Yes — recommended minimum |
| Use for data integrity | Avoid (collision risk) | Yes — standard choice | No — non-deterministic, not suitable |
MD5 — Deep Dive
MD5 was designed by Ron Rivest in 1991 and was the dominant checksum and password hashing algorithm through the 2000s. It produces a 128-bit digest in nanoseconds — so fast that a single modern GPU (Nvidia RTX 4090) can compute approximately 164 billion MD5 hashes per second.
Why MD5 is broken for security. Collision attacks — finding two different inputs that produce the same MD5 output — were demonstrated by researchers in 2004 and fully automated by 2005. By 2008, researchers created a rogue SSL certificate by exploiting MD5 collisions in certificate authorities. The attack was practical on consumer hardware. MD5 is now on the explicit "do not use" list in every major security standard (NIST SP 800-131A, PCI DSS, OWASP).
Password cracking. Even setting aside collision attacks, MD5 is unsuitable for passwords because of raw speed. An attacker who obtains an MD5 password hash can test every entry in the RockYou wordlist (14 million passwords) in under 1 millisecond. With rules and variations, billions of candidates are testable per second. The 2012 LinkedIn breach exposed 6.5 million unsalted SHA-1 hashes; a similar breach with MD5 would be cracked within seconds.
Where MD5 still appears. MD5 checksums are still published alongside software downloads to catch transmission errors. In a non-adversarial context (you own both the file and the checksum and the threat is only accidental corruption), MD5 is technically sufficient. It is also used for non-cryptographic purposes: generating cache keys, deduplicating files in private storage, and hash maps where collision resistance is not a security requirement. For any of these, SHA-256 is equally fast from a user perspective and removes the security question entirely.
The verdict on MD5: use it nowhere in a security context. Replace legacy MD5 password hashes immediately — a common migration strategy is to re-hash the existing MD5 hash with bcrypt on first login and store the new hash going forward.
SHA-256 — Deep Dive
SHA-256 is part of the SHA-2 family, standardised by NIST in 2001. It produces a 256-bit digest (64 hex characters) with no known collisions. SHA-256 underpins virtually every security-critical system in modern infrastructure: TLS certificate fingerprinting, code signing, digital signatures, HMAC authentication, and blockchain proof-of-work.
Where SHA-256 is the right tool. SHA-256 is designed for integrity and authentication — verifying that data has not been altered. It is deterministic (same input → same output), collision resistant, and fast enough to process large files or high-frequency network traffic without becoming a bottleneck. Practical uses:
- File integrity.
sha256sum file.tar.gzon Linux produces a digest you can publish alongside a download. Downloaders verify the computed digest matches the published one. - Digital signatures. TLS 1.3 mandates SHA-256 for certificate signatures. Your browser's HTTPS padlock relies on SHA-256 to verify the server certificate has not been forged.
- HMAC-SHA256. The standard for API request signing (AWS Signature Version 4, GitHub webhook signatures, Stripe webhook verification). The HMAC construction uses a secret key so that an attacker without the key cannot forge a valid MAC.
- Blockchain. Bitcoin's proof-of-work and transaction IDs use double-SHA-256. Ethereum uses Keccak-256.
Why SHA-256 fails for passwords. Speed is SHA-256's strength for data integrity and its fatal weakness for passwords. A modern GPU computes approximately 1 billion SHA-256 hashes per second. If an attacker obtains a SHA-256 password hash, they can test every entry in common wordlists, every 8-character alphanumeric combination, and every known password pattern from previous breaches in minutes to hours. Adding a random salt (stored alongside the hash) defeats rainbow tables but does nothing to slow per-hash computation speed. The attacker still tests 1 billion candidates per second per GPU.
SHA-256 vs SHA-512. SHA-512 produces a longer 512-bit digest and is faster than SHA-256 on 64-bit CPUs (the algorithm operates on 64-bit words internally). SHA-256's 128-bit security level is sufficient for all current applications. Prefer SHA-256 for compatibility; use SHA-512 when a longer output is explicitly needed (e.g., key derivation contexts).
bcrypt — Deep Dive
bcrypt was designed by Niels Provos and David Mazières in 1999 specifically for password hashing. Its core insight: password hashing should be slow — tunable slow — so that the cost of brute-force remains high even as hardware improves.
The cost factor. bcrypt's work factor (cost) is an integer that controls the number of iterations: the algorithm performs 2^cost key schedule rounds. At cost 10, hashing takes approximately 100ms on a modern server. At cost 12, approximately 250ms. At cost 14, approximately 1 second. An attacker testing 1 billion passwords per second against MD5 can test only about 4,000 passwords per second against bcrypt at cost 12 (on the same hardware). The cost factor can be increased over time as hardware improves — OWASP recommends re-evaluating every two years.
Built-in salting. bcrypt generates a cryptographically random 128-bit salt for every hash and embeds it in the output string. The 60-character output encodes the algorithm version, cost factor, salt, and hash in a single self-contained string. During verification, the function extracts the salt and cost from the stored string and re-hashes the candidate — no separate storage needed. Two identical passwords hashed with bcrypt produce different outputs, making rainbow tables completely useless.
The 72-byte limit. bcrypt processes only the first 72 bytes of input; anything beyond is silently discarded. For most real-world passwords this is not an issue (the median password is under 20 characters). For systems that explicitly encourage long passphrases, the standard mitigation is to pre-hash the password with SHA-256 (producing a 32-byte value) before passing to bcrypt. This requires care: some bcrypt implementations treat a null byte in the pre-hashed output as a string terminator, so use the hex or base64 representation of the SHA-256 digest rather than raw bytes.
bcrypt vs Argon2id. Argon2id won the Password Hashing Competition in 2015 and is OWASP's first recommendation for new systems as of 2026. Argon2id adds a configurable memory cost parameter (the algorithm requires a minimum amount of RAM per hash), making it resistant to GPU attacks that parallelise thousands of low-memory bcrypt computations. OWASP's current minimum configuration for Argon2id: memory 19 MiB, iterations 2, parallelism 1. For new systems, implement Argon2id. For existing systems using bcrypt at cost 12+, migration is non-urgent — bcrypt remains secure in practice.
bcrypt in the wild. PHP's password_hash() defaults to bcrypt. Node.js's bcrypt and bcryptjs libraries are widely used. Spring Security defaults to bcrypt at cost 10. PostgreSQL's pgcrypto extension includes bcrypt. If your framework provides a password hashing helper, use it — framework defaults are usually correct and save you from implementation errors.
When to Use MD5
The honest answer is: rarely, and never for security. Acceptable non-security uses in 2026:
- Generating non-security-sensitive cache keys where speed matters and collision probability is irrelevant.
- File deduplication in a private, non-adversarial system where the threat model excludes a malicious actor crafting collisions.
- Legacy system compatibility when you cannot change what the counterparty sends or stores.
In every case, ask whether SHA-256 would work instead. SHA-256 is just as fast from a human perspective, has no known weaknesses, and removes any future security question. The only reason to choose MD5 is when an external system forces your hand.
When to Use SHA-256
SHA-256 is the right choice for:
- File integrity verification (checksums published alongside downloads).
- Digital signatures and certificate fingerprinting (TLS, code signing, S/MIME).
- HMAC message authentication (API signing, webhook verification, cookie integrity).
- Blockchain and distributed ledger applications.
- Key derivation (as an input to HKDF or PBKDF2 — not standalone for passwords).
- Content-addressable storage (Git uses SHA-1 historically, newer formats migrate to SHA-256).
Do not use raw SHA-256 for passwords even with a salt. The speed that makes it excellent for data integrity makes it dangerous for password storage.
When to Use bcrypt
bcrypt (or Argon2id for new implementations) is the only appropriate choice for:
- Storing user passwords in any application.
- Any secret that a user supplies at login and that needs to be verified later.
- API key storage when you need to verify the key without storing it in plaintext.
Use a cost factor of at least 12 on server hardware in 2026. Benchmark on your actual production hardware — a cost factor that takes 250ms on a dedicated server may take 2 seconds on a shared virtual machine with limited CPU allocation.
Our Verdict
The rules are simple and absolute:
For passwords: use bcrypt at cost 12+ (or Argon2id for new systems). Never MD5. Never raw SHA-256. The history of credential breaches — LinkedIn, RockYou, Adobe, Yahoo — is largely a history of password databases hashed with fast algorithms. Do not add your application to that list.
For data integrity, signatures, and MACs: use SHA-256. It has no known weaknesses, is universally supported, and is the standard for TLS, code signing, HMAC, and blockchain. Use HMAC-SHA256 when authentication (not just integrity) is needed.
For MD5: the only legitimate reason is legacy compatibility or non-adversarial deduplication. If you can choose, choose SHA-256 instead.
The Hash Generator lets you compute MD5, SHA-256, SHA-512, and other digests instantly to understand output formats and test implementations.