DevBolt
·9 min read

SHA-256 vs MD5: Why MD5 Is Broken and What to Use Instead

SecurityCryptographyComparison

MD5 and SHA-256 are both hash functions that produce a fixed-length digest from any input. MD5 produces a 128-bit hash. SHA-256 produces a 256-bit hash. The critical difference: MD5 is cryptographically broken. This guide covers what that means, when each is appropriate, and the practical code to use them.

Quick Comparison

PropertyMD5SHA-256
Output size128 bits (32 hex chars)256 bits (64 hex chars)
SpeedVery fastFast (slower than MD5)
Collision resistanceBroken (collisions found in seconds)Strong (no practical collisions known)
Pre-image resistanceWeakenedStrong
Year introduced19922001 (NSA / NIST)
First collision2004 (Wang et al.)None found
OK for security?NoYes
OK for checksums?Yes (non-adversarial)Yes

What “Broken” Means

A hash function is broken when someone can produce two different inputs that generate the same hash output (a collision). For MD5, this was demonstrated practically in 2004 and weaponized in real attacks:

  • 2008: Rogue CA certificate. Researchers created a fraudulent SSL certificate authority using MD5 collisions, allowing man-in-the-middle attacks on HTTPS.
  • 2012: Flame malware. State-sponsored malware used MD5 collisions to forge Windows Update signatures, spreading to millions of machines.
  • Today: Collisions in seconds. Tools like HashClash generate MD5 collisions on a laptop in under a minute. The attack is trivial.

SHA-256 has no known collision attacks. The theoretical security margin is 2128 operations for a collision — far beyond current computing capabilities, including quantum computers.

The Output

Hashing 'Hello, World!'
MD5:    65a8e27d8879283831b664bd8b7f0ad4
SHA-256: dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f

SHA-256 output is twice as long (64 hex characters vs 32). Both are deterministic — the same input always produces the same output.

Code Examples

Node.js

Node.js (crypto)
const crypto = require('crypto');

// SHA-256 — use this
const sha256 = crypto.createHash('sha256')
  .update('Hello, World!')
  .digest('hex');

// MD5 — only for non-security checksums
const md5 = crypto.createHash('md5')
  .update('Hello, World!')
  .digest('hex');

Python

Python (hashlib)
import hashlib

# SHA-256
sha256 = hashlib.sha256(b"Hello, World!").hexdigest()

# MD5
md5 = hashlib.md5(b"Hello, World!").hexdigest()

Browser (Web Crypto API)

JavaScript (browser)
async function sha256(message) {
  const data = new TextEncoder().encode(message);
  const hash = await crypto.subtle.digest('SHA-256', data);
  return Array.from(new Uint8Array(hash))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
}

// Note: Web Crypto API does NOT support MD5
// — browsers intentionally exclude broken algorithms

Command Line

Shell
# SHA-256
echo -n "Hello, World!" | sha256sum
# dffd6021bb2bd5b0af676290809ec3a5...

# MD5
echo -n "Hello, World!" | md5sum
# 65a8e27d8879283831b664bd8b7f0ad4

When MD5 Is Still OK

MD5 is only appropriate in non-adversarial contexts where nobody is trying to forge data:

  • Cache keys / deduplication. Checking if a file has changed for caching purposes. Speed matters, security doesn't.
  • Data integrity (trusted sources). Verifying a file wasn't corrupted during a local copy — not verifying it wasn't tampered with.
  • Legacy system compatibility. When you must interact with systems that only support MD5 and migration isn't possible.

When to Use SHA-256

  • File integrity verification. Verifying downloads, checking software signatures, comparing files across untrusted networks.
  • Digital signatures. HMAC-SHA256 for API authentication, JWT signing, webhook verification.
  • Certificate chains. TLS/SSL certificates use SHA-256. Browsers reject SHA-1 and MD5 certificates.
  • Blockchain and merkle trees. Bitcoin and most blockchains use SHA-256 for block hashing and transaction verification.

Neither is for Password Hashing

Do not use MD5 or SHA-256 for passwords. Both are designed to be fast — which is exactly what you don't want. An attacker with a GPU can compute billions of SHA-256 hashes per second. Use purpose-built password hashing algorithms instead:

  • bcrypt — time-tested, widely supported, configurable cost factor
  • scrypt — memory-hard, resists GPU/ASIC attacks
  • Argon2id — winner of the Password Hashing Competition, current best practice

Building authentication systems?

Cloudways provides managed hosting with built-in security features, free SSL certificates, and automated backups — so you can focus on your application logic.

The Verdict

Default to SHA-256. It's fast enough for any use case where MD5 would be used, and it provides real security guarantees. Use MD5 only when you specifically need backward compatibility with legacy systems and there is no security requirement. For passwords, use bcrypt or Argon2id — never a general-purpose hash.

Try It Yourself

Generate MD5, SHA-1, SHA-256, SHA-384, and SHA-512 hashes instantly with our Hash Generator. Verify file integrity with the File Hash Calculator, or generate strong passwords with the Password Generator.