X Xerobit

MD5 Is Dead. Use These Instead.

MD5 was broken in 2004 and is trivially cracked for passwords. Here's what to use instead for checksums, passwords, and message authentication — and why it matters.

Mian Ali Khalid · · 7 min read
Use the tool
Hash Generator
Generate MD5, SHA-1, SHA-256, and SHA-512 hashes client-side.
Open Hash Generator →

MD5 was designed in 1991 by Ronald Rivest. For its time it was reasonable: fast, 128-bit output, widely implemented. In 2004, Wang and Yu published a technique that produced MD5 collisions in hours on a desktop CPU. By 2008, creating rogue CA certificates using MD5 collisions was demonstrated live. Today a modern GPU can compute roughly 164 billion MD5 hashes per second. MD5 is not “somewhat weak” — it is actively broken for security purposes.

The Hash Generator on this site supports MD5 for legacy compatibility: checking old checksums, interoperating with systems you didn’t design. For anything new, use SHA-256 or SHA-512.

Here’s exactly what to use for each job, and why.

Why MD5 fails

Collision attacks

A hash collision is two different inputs that produce the same output. Wang and Yu’s 2004 result showed MD5 collisions could be computed in minutes. Marc Stevens improved this in 2012 with a chosen-prefix collision: you can construct two documents with chosen content that share the same MD5. That technique is how the Flame malware forged a Microsoft code-signing certificate — making malicious software appear signed by Microsoft.

For practical file integrity: if you use MD5 to verify a downloaded file, an attacker can craft a malicious file that has an identical MD5 to the legitimate one. Your integrity check passes. You have no actual guarantee.

Password storage catastrophe

This is where MD5 causes the most ongoing damage. The problem is speed — and speed is exactly what you do not want for password hashing.

GPU hash rates (RTX 4090):

AlgorithmHashes per second
MD5~164 billion
SHA-256~22 billion
bcrypt (cost=12)~184,000
argon2id~600

bcrypt is designed to be slow. Argon2id is designed to be both slow and memory-hard — making GPU farms uneconomical. MD5 is optimized for speed, which means an attacker with a consumer GPU can try 164 billion password guesses per second against a leaked MD5 database.

HaveIBeenPwned has cracked hundreds of millions of MD5-hashed passwords from real breaches. Salted MD5 is crackable at GPU speed. This is not a theoretical risk.

SHA-1 has the same problem

While you’re here: SHA-1 is also broken. Google’s SHAttered attack (2017) produced the first real-world SHA-1 collision demonstrated on two PDF files. Chrome removed SHA-1 certificate trust in 2017. SHA-1 has the same speed problem as MD5 for passwords — about 8 billion hashes/second on modern GPUs.

The replacement is the same: SHA-256 or SHA-3 for data integrity; argon2/bcrypt/scrypt for passwords.

The right algorithm for each job

File checksums and data integrity

Use SHA-256. There are no known practical collision attacks. It produces a 256-bit digest and is hardware-accelerated on most modern CPUs (SHA-NI instructions on x86, Apple Silicon). Speed is fine here — checksums involve no secret, so a fast hash is correct.

# Linux / macOS
sha256sum myfile.tar.gz

# macOS only
shasum -a 256 myfile.tar.gz

# PowerShell
Get-FileHash myfile.zip -Algorithm SHA256

If you want post-quantum conservatism, SHA-3 (Keccak-256) is NIST-standardized and has no structural relation to SHA-2.

Password storage

Use one of these, in preference order:

1. Argon2id — winner of the Password Hashing Competition (2015). Memory-hard and time-hard. Resistant to GPU and ASIC attacks. Recommended by OWASP for new systems.

# Python — argon2-cffi
from argon2 import PasswordHasher
ph = PasswordHasher(time_cost=2, memory_cost=65536, parallelism=2)
hash = ph.hash("user_password")
ph.verify(hash, "user_password")  # True
// Node — argon2 package
const argon2 = require('argon2');
const hash = await argon2.hash('password', { type: argon2.argon2id });
await argon2.verify(hash, 'password');

2. bcrypt — designed 1999, battle-tested, available in every language. One caveat: bcrypt truncates input at 72 bytes, so very long passwords get silently truncated. Compensate by pre-hashing with SHA-256 if you want arbitrary-length support.

3. scrypt — memory-hard, designed by Colin Percival. Available natively in Node.js as crypto.scrypt. Good if argon2 isn’t available.

Never use MD5, SHA-1, SHA-256, or SHA-512 directly for passwords — even with a salt. They are fast by design.

Message authentication (HMAC)

Legacy systems sometimes use HMAC-MD5 for signing API requests or webhook payloads. While HMAC-MD5 is more resilient than bare MD5 (the collision attack does not directly transfer to HMAC), there is no reason to use it in new code.

Use HMAC-SHA256 — it is the standard for every modern protocol (AWS Signature V4, JWT HS256, Stripe webhook signatures, Slack webhook verification).

import hmac, hashlib
signature = hmac.new(
    key.encode('utf-8'),
    message.encode('utf-8'),
    hashlib.sha256
).hexdigest()
const crypto = require('crypto');
const sig = crypto.createHmac('sha256', key).update(message).digest('hex');

Non-cryptographic use cases

MD5 is still fine when there is no security requirement: cache-busting query parameters, deduplication of non-sensitive content, legacy format compatibility. Speed is a feature there, not a bug. Just never call it a security control.

Migrating an existing MD5 password database

You cannot rehash cold — you don’t have the plaintexts. The standard migration path:

  1. Wrap on login: when a user successfully authenticates against the old MD5 hash, immediately rehash the plaintext password with argon2/bcrypt and replace the stored hash.
  2. Set a forced-reset deadline: users who haven’t logged in within N months get a mandatory password reset email. This handles dormant accounts.
  3. Optional bridge: store bcrypt(sha256(password)) instead of bare MD5 during transition. Not ideal (SHA-256 of the password gives you a fixed-length input, losing entropy for very short passwords), but it removes the instant-crack risk before migration completes.

The important thing is to start. Migrate new logins first; force-reset the rest on a timeline you can defend.

Using the Hash Generator

The Hash Generator computes MD5, SHA-1, SHA-256, and SHA-512 entirely in your browser — nothing is sent to a server. Use it to verify file downloads, compare algorithm output lengths, or audit what hash formats you’re actually dealing with.

Further reading


Related posts

Related tool

Hash Generator

Generate MD5, SHA-1, SHA-256, and SHA-512 hashes client-side.

Written by Mian Ali Khalid. Part of the Encoding & Crypto pillar.