MD5 vs SHA: Understanding Cryptographic Hash Functions
Cryptographic hash functions are a cornerstone of modern security — used in digital signatures, TLS certificates, password storage, file integrity verification, and blockchains. Yet many developers still reach for MD5 or SHA-1 out of habit, unaware that both have been cryptographically broken for years. This guide explains what makes a hash function secure, where each algorithm fits, and what you should be using today.
What is a Hash Function?
A cryptographic hash function takes an input of any length and produces a fixed-size output (the hash, digest, or checksum). Four properties define a secure hash function:
- Deterministic — the same input always produces the same output.
- Fast to compute — the hash of any input should be quick to calculate.
- Pre-image resistant — given a hash, it should be computationally infeasible to find an input that produces it.
- Collision resistant — it should be computationally infeasible to find two different inputs that produce the same hash.
A "broken" hash function is one where researchers have found practical attacks against properties 3 or 4.
MD5: Fast but Broken
MD5 (Message Digest 5) was designed in 1991 and produces a 128-bit (32 hex character) hash. It was widely used for file checksums, password storage, and digital signatures for over a decade.
MD5("hello") = 5d41402abc4b2a76b9719d911017c592
MD5 has been considered cryptographically broken since 2004. Researchers can generate collision attacks in seconds on modern hardware — meaning two different inputs can be crafted to produce the same MD5 hash. This breaks its use in digital signatures and certificates.
MD5 is still acceptable for non-cryptographic purposes like checksumming files for accidental corruption detection (not malicious tampering), or as a fast hash in hash tables. For anything security-related, retire it immediately.
SHA-1: Also Deprecated
SHA-1 (Secure Hash Algorithm 1) produces a 160-bit (40 hex character) hash. It was widely used in SSL/TLS certificates, Git commit IDs, and code signing until it was theoretically broken in 2005. In 2017, Google's SHAttered attack produced the first practical SHA-1 collision, generating two different PDFs with the same SHA-1 hash.
Major browsers stopped accepting SHA-1 TLS certificates in 2017. Git still uses SHA-1 internally for object IDs but is transitioning to SHA-256. Do not use SHA-1 for new security-sensitive applications.
SHA-256 and SHA-512: The Modern Standard
SHA-256 and SHA-512 are part of the SHA-2 family, standardised in 2001. No practical attacks are known against either. SHA-256 produces a 256-bit (64 hex character) hash; SHA-512 produces a 512-bit (128 hex character) hash.
SHA-256("hello") =
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
SHA-256 is the workhorse of modern cryptography: used in TLS 1.3, Bitcoin, AWS request signing, JWT HMAC signatures, and file integrity in package managers. Use SHA-256 as your default for integrity checks and digital signatures.
HMAC: Keyed Hashing
HMAC (Hash-based Message Authentication Code) combines a hash function with a secret key to produce a message authentication code. Unlike a plain hash, an HMAC can only be verified by someone who knows the secret key, providing both integrity and authenticity.
HMAC-SHA256(key="secret", message="Hello") =
88aab3ede8d3adf94d26ab90d3bafd4a2083070c3bcce9c014ee04a443847c0b
HMAC-SHA256 is used in JWT signature verification (HS256), AWS request signing (SigV4), webhook signature verification, and API authentication tokens.
Hashing Passwords: bcrypt and Argon2
For password storage, fast hash functions like SHA-256 are a security liability. A modern GPU can compute billions of SHA-256 hashes per second, making brute-force attacks trivially fast. Password hashing requires a deliberately slow function:
- bcrypt — designed in 1999, still the most widely deployed. Has a configurable work factor (cost).
bcrypt(password, cost=12)takes ~250ms — fast enough for login, too slow for brute force. - Argon2id — winner of the 2015 Password Hashing Competition. Memory-hard (resists GPU attacks), configurable time and memory cost. Preferred for new systems.
- scrypt — also memory-hard, used by many cryptocurrency systems.
All three automatically handle salting internally. Never use MD5, SHA-1, or SHA-256 directly for password storage.
Hash Collisions and Rainbow Tables
A hash collision is when two different inputs produce the same hash. Collisions are inevitable in theory (infinite inputs, finite outputs), but a secure hash makes them computationally infeasible to find intentionally.
A rainbow table is a precomputed lookup table mapping common passwords and their hash values. An attacker who steals your password database can look up hashes in seconds. Salting defeats rainbow tables: a random salt is appended to each password before hashing, so identical passwords produce different hashes, and precomputed tables are useless.
Which Hash Should You Use?
Use the Hash Generator at Tools.Fun to generate MD5, SHA-1, SHA-256, and SHA-512 hashes for any input — useful for verifying file checksums, generating test vectors, and understanding hash outputs. For production systems: SHA-256 for integrity, HMAC-SHA256 for authentication, and bcrypt/Argon2id for passwords.
← Back