MD5 vs SHA-256 vs SHA-512 — Hash Functions Explained
Hash functions are everywhere in software development: file integrity checks, password storage, digital signatures, API authentication, caching keys, deduplication. Yet most developers work with them as black boxes — you feed in a string, you get back a fixed-length hex digest. The details of which hash function to use, and which to avoid, turn out to matter a great deal.
MD5 is broken. SHA-1 is deprecated. SHA-256 and SHA-512 are currently secure. SHA-3 exists if you want future-proofing. But "broken" does not mean the same thing in every context — MD5 is fine for some use cases and disastrously wrong for others. This guide explains the properties that matter, how each function stands against them, and gives you a clear decision framework for choosing the right hash in 2026.
What a Hash Function Actually Does
A cryptographic hash function maps an input of arbitrary length to a fixed-length output (the digest or hash). Three properties define a cryptographically secure hash function:
- Preimage resistance — given a hash
h, it should be computationally infeasible to find any inputmsuch thathash(m) = h. This is the "one-way" property. - Second preimage resistance — given an input
m1, it should be infeasible to find a different inputm2such thathash(m1) = hash(m2). - Collision resistance — it should be infeasible to find any two distinct inputs
m1andm2such thathash(m1) = hash(m2).
A function that fails any of these properties is considered broken for cryptographic use. Note that "infeasible" has a specific meaning here: it does not mean mathematically impossible, it means requiring more computation than is practical with current or foreseeable hardware.
Additionally, cryptographic hash functions exhibit the avalanche effect: changing a single bit in the input produces an output that differs in approximately half of its bits. This ensures that similar inputs produce completely different digests.
Input: "hello"
MD5: 5d41402abc4b2a76b9719d911017c592 (128-bit / 32 hex chars)
Input: "Hello"
MD5: 8b1a9953c4611296a827abf8c47804d7 (one character change = completely different output) MD5 — Fast, Ubiquitous, and Broken
History and design
MD5 (Message Digest 5) was designed by Ron Rivest in 1991 and produces a 128-bit (16-byte) digest. For most of the 1990s it was the standard choice for file integrity verification, certificate signing, and password hashing. It is extremely fast — a modern CPU can compute tens of millions of MD5 hashes per second, and a GPU can compute billions.
Why MD5 is broken
In 2004, Xiaoyun Wang and colleagues demonstrated a practical collision attack against MD5 — two different files that produce the same MD5 hash. The attack runs in minutes on consumer hardware. In 2008, researchers created a rogue CA certificate using an MD5 collision, demonstrating that real-world PKI infrastructure was vulnerable. By 2012, the Flame malware used an MD5 collision to forge a Microsoft code signing certificate.
The NIST officially deprecated MD5 for most cryptographic uses. Certificate authorities stopped issuing MD5-signed certificates by 2009. Browser vendors removed support for MD5 certificate signatures around 2011.
When MD5 is still acceptable
MD5 is not universally useless. For non-security checksums — detecting accidental data corruption in file transfers, content-based addressing in a caching system where the attacker cannot influence the inputs, or generating unique identifiers in a closed internal system — MD5 remains adequate. The key test: if an attacker can benefit from creating a collision, do not use MD5. If only accidental corruption matters, MD5 is fine.
- Safe: internal deduplication, cache keys, non-security file change detection
- Unsafe: certificates, digital signatures, password hashing, file authenticity verification, security tokens
SHA-1 — Deprecated, Not Dead Yet
SHA-1 produces a 160-bit digest and was the successor to MD5. It remained the standard for certificate signing and code signing through most of the 2000s. In 2017, the SHAttered attack demonstrated the first practical SHA-1 collision, producing two different PDF files with identical SHA-1 hashes using approximately 110 GPU-years of computation — expensive but well within nation-state budgets and increasingly accessible.
SHA-1 is deprecated by NIST and all major certificate authorities. It should not be used for certificates, code signing, or any new security-sensitive application. Some legacy systems still use SHA-1 internally, but migration to SHA-256 is strongly recommended. Git still uses SHA-1 for object addressing (though SHA-256 transition is underway), but this is being phased out.
SHA-256 — The Current Standard
SHA-256 is part of the SHA-2 family, designed by the NSA and standardized by NIST in FIPS 180-4. It produces a 256-bit (32-byte) digest. SHA-256 has been intensively analyzed since its publication in 2001 and no practical attack has been found. It is the de facto standard for:
- TLS certificates (essentially all certificates issued today use SHA-256)
- Code signing (Windows Authenticode, Apple notarization, JARs)
- HMAC-SHA256 for API authentication (AWS Signature v4, GitHub webhook verification)
- JWT token signatures (HS256 and RS256 both use SHA-256 internally)
- Blockchain transaction IDs (Bitcoin uses double-SHA256)
- File integrity verification in package managers (npm, pip, apt)
Input: "hello"
SHA-256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
(256-bit / 64 hex chars)
SHA-512: 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d
99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
(512-bit / 128 hex chars) Performance of SHA-256
SHA-256 uses 32-bit word operations internally. On 32-bit hardware or older CPUs without hardware acceleration, it is noticeably slower than MD5. On modern 64-bit CPUs with SHA extensions (Intel Goldmont+, AMD Zen+, Apple Silicon, ARM Cortex-A57+), SHA-256 is hardware-accelerated and extremely fast — often approaching MD5 speeds. Most server environments have hardware acceleration, so in practice SHA-256 is fast enough for virtually all applications.
SHA-512 — Wider, Sometimes Faster
SHA-512 produces a 512-bit (64-byte) digest using 64-bit word operations internally. On 64-bit hardware without SHA extensions, SHA-512 can actually be faster than SHA-256 because its 64-bit operations make better use of modern register widths. On hardware with SHA extensions, SHA-256 is typically faster because the extensions are specifically optimized for SHA-256.
SHA-512 provides a larger security margin — 256-bit collision resistance versus 128-bit for SHA-256. For most current threat models, SHA-256's 128-bit collision resistance is more than sufficient (breaking it would require roughly 2^128 operations). SHA-512 is appropriate when:
- You are targeting 64-bit servers and want maximum throughput without hardware extensions
- You need longer digests as key material for other cryptographic operations
- You want additional security margin for data that must remain protected over decades
- You are implementing protocols that specifically call for SHA-512 (e.g., some TLS cipher suites)
SHA-384 and SHA-512/256
SHA-384 is a truncated version of SHA-512 producing 384 bits — useful when you want the 64-bit internal operations of SHA-512 but need shorter output. SHA-512/256 is another truncated variant that produces 256-bit output using SHA-512's internal computation. SHA-512/256 is resistant to length extension attacks that affect SHA-256, making it useful in contexts where length extension is a concern (though HMAC already mitigates this in most practical scenarios).
SHA-3 — Different Architecture, Future-Proof
SHA-3 (standardized in NIST FIPS 202, 2015) uses the Keccak sponge construction — a fundamentally different design from SHA-2's Merkle-Damgard structure. This is important because any future weakness discovered in the Merkle-Damgard design would affect MD5, SHA-1, and SHA-2 simultaneously, while SHA-3 would remain unaffected.
SHA-3 is currently secure and is the right choice for new systems that need long-term assurance or that want to hedge against future SHA-2 weaknesses. It is slower than SHA-256 in pure software implementations. Where SHA-3 shines is in hardware implementations — its design is very efficient in silicon. SHA-3-256 and SHA-3-512 produce the same digest sizes as their SHA-2 counterparts.
Comparison Table
| Algorithm | Output | Collision Resist. | Status | Speed (SW) | Use for passwords? |
|---|---|---|---|---|---|
| MD5 | 128-bit | Broken | Deprecated | Very fast | Never |
| SHA-1 | 160-bit | Broken | Deprecated | Fast | Never |
| SHA-256 | 256-bit | 128-bit | Current standard | Fast (HW accel) | Never (too fast) |
| SHA-512 | 512-bit | 256-bit | Secure | Fast on 64-bit | Never (too fast) |
| SHA-3-256 | 256-bit | 128-bit | Future-proof | Moderate (SW) | Never (too fast) |
| bcrypt | 60-char string | N/A | Passwords only | Intentionally slow | Yes |
Password Hashing: A Completely Different Problem
This deserves its own section because it is one of the most common mistakes developers make. SHA-256 is the right tool for file integrity checks, API signing, and certificate verification. It is the wrong tool for hashing passwords, and using it for that purpose causes real security incidents.
The problem is speed. SHA-256 is designed to be fast — a modern GPU can compute billions of SHA-256 hashes per second. An attacker who obtains your hashed password database can attempt billions of password guesses per second. Even a long, random password can be cracked quickly if the hash is fast.
// NEVER do this for passwords
const hash = crypto.createHash('sha256').update(password).digest('hex'); // Use bcrypt, scrypt, or Argon2 for passwords
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12); // cost factor 12 The Bcrypt Test tool lets you hash and verify bcrypt passwords in the browser. For understanding bcrypt cost factors and their computation time, it is a useful reference when configuring your application's work factor.
HMAC: Adding Authentication to a Hash
A plain hash proves nothing about who computed it — anyone who has the data can compute the same SHA-256 hash. HMAC (Hash-based Message Authentication Code) adds a secret key to the computation, producing a tag that can only be reproduced by someone who knows the key. HMAC-SHA256 is the standard for:
- Webhook signature verification (GitHub, Stripe, Shopify all use HMAC-SHA256)
- AWS Signature Version 4 (request signing)
- JWT HS256 tokens (HMAC-SHA256 of header + payload)
- Cookie integrity (signing session cookies to prevent tampering)
const crypto = require('crypto');
// Sign a message with HMAC-SHA256
const mac = crypto
.createHmac('sha256', secretKey)
.update(message)
.digest('hex');
// Verify: compare in constant time (prevents timing attacks)
const isValid = crypto.timingSafeEqual(
Buffer.from(mac, 'hex'),
Buffer.from(received, 'hex')
);
Note the use of timingSafeEqual for comparison. Comparing MAC values with a regular string equality check leaks timing information that can be exploited in a timing attack. Always use a constant-time comparison function when verifying MACs. Use the HMAC Generator to compute HMAC-SHA256 values for testing and debugging without writing code.
Real-World Recommendations
General file integrity (checksums)
Use SHA-256. It is the standard for package verification (npm lockfiles, pip requirements hashes, Docker image layers). The SHA-256 Hash tool computes SHA-256 digests in your browser for text input or string values. For quick non-security checksums where speed is critical and you trust the source, MD5 remains acceptable but SHA-256 is preferable in any shared or automated context.
TLS certificates and code signing
SHA-256 is the required standard. All certificate authorities issue SHA-256 certificates. Never use MD5 or SHA-1 for new certificates — they will be rejected by modern browsers and operating systems.
API authentication
Use HMAC-SHA256. It is the established standard, well-supported in all languages, and the algorithm expected by most API security documentation. Compute digests with the MD5 Hash tool or SHA-256 Hash tool for quick comparisons, and generate HMAC signatures with the HMAC Generator.
Password hashing
Use bcrypt (cost factor 12+), scrypt, or Argon2id. Never use MD5, SHA-1, SHA-256, or SHA-512 directly for passwords, even with salting. The Bcrypt Test tool can help you verify bcrypt hashes during development.
Long-lived data requiring decades of security
Prefer SHA-512 or SHA-3-256. The larger digest size provides additional margin against advances in cryptanalysis. NIST recommends SHA-512 and SHA-3 for applications requiring long-term security. See the official guidance in NIST FIPS 180-4 for the authoritative specification of SHA-2 algorithms.
New systems without legacy constraints
SHA-256 for general use. Argon2id for passwords. HMAC-SHA256 for authentication codes. If you want future-proofing and can accept slightly lower performance, SHA-3-256 is a solid alternative to SHA-256 for general-purpose hashing.