Skip to main content
Security

Hashing algorithms: MD5, SHA-2, bcrypt, and Argon2 are not interchangeable

Pick hashes by job: fast hashes for integrity, password-hashing functions for passwords, and no hand-rolled crypto substitutions when the threat model changes.

Thien Nguyen
By Thien Nguyen
Updated June 18, 2026 · 2 min read

The question is never “which hash is best?” It is “what am I hashing, and what attack am I slowing down?” A fast hash is a feature for file integrity and a disaster for stored passwords.

Short answer: use SHA-256 or SHA-512 for integrity when the attacker cannot replace the expected digest; use Argon2id for new password storage; use bcrypt only where compatibility makes it necessary; do not use MD5 or SHA-1 for security decisions. The OWASP password-storage cheat sheet recommends Argon2id and gives current parameter guidance.

JobUseDo not use
Download checksumSHA-256 plus a trusted published digest/signatureMD5 as a tamper guarantee
Password storageArgon2id with a unique saltPlain SHA-256, even salted
Legacy password verificationbcrypt while planning migrationA forced reset without a migration path
Message authenticationHMAC-SHA-256sha256(secret + message)

Password hashes must be expensive

// Pseudocode: use a maintained Argon2 library, not this as a crypto implementation.
const encoded = await argon2id.hash(password, { memoryCost: 19456, timeCost: 2, parallelism: 1 });
const ok = await argon2id.verify(encoded, suppliedPassword);

The encoded result carries the algorithm, salt, and work parameters. That makes gradual upgrades possible: on a successful login, verify the old hash, then rehash with stronger parameters.

Encryption is reversible with a key. Hashing is one-way. Encrypting passwords so you can recover them later is usually a design bug, not a convenience.

The mistake behind “we use SHA-256”

SHA-256 is designed to be fast. An attacker with a stolen password database can make enormous numbers of guesses cheaply; salts stop precomputed rainbow tables but do not make guessing expensive. Argon2id and bcrypt are deliberately slow, and Argon2id also consumes memory, which raises the cost of parallel guessing.

Pick the primitive by purpose, store passwords with a maintained password-hashing library, and benchmark parameters on your own hardware. Crypto names are not interchangeable labels.

Cover photo by Laura Gigch on Pexels.

References

Primary documentation and specifications checked when this article was last updated.

SecurityCryptographyPasswords

Related articles

All articles