If you've ever downloaded a Linux ISO and noticed a .sha256 file next to it, you've encountered a cryptographic hash. If you've ever stored passwords in a database, the choice of hash algorithm is one of the most consequential decisions in your codebase.
This guide covers what hashes actually do, the real difference between MD5, SHA-1, SHA-256, and SHA-512 — and the one mistake that trips up developers every time.
What is a cryptographic hash?
A hash function takes any amount of input data and produces a fixed-length output called a digest. Three properties make cryptographic hashes useful:
- Deterministic: the same input always produces the same output
- Avalanche effect: changing even one bit of input produces a completely different hash
- One-way: you cannot reverse the output back to the input (practically speaking)
Here are the SHA-256 hashes of two nearly identical strings:
"hello" → 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
"Hello" → 185f8db32921bd46d35cc85e1bf7ede3e154d00002aaa6f5e23ae74a75b31fc4
One capital letter. Completely different hash.
MD5 — fast, broken, still everywhere
Output: 128 bits (32 hex characters)
MD5 was designed in 1991 and is still widely used for non-security purposes. The problem: researchers demonstrated MD5 collision attacks in 2004. By 2008, MD5-signed certificates were being forged in practice.
When it's fine to use MD5:
- File integrity checks where you control both ends (internal deduplication, cache keys)
- Checksums for non-security purposes (e.g. comparing large downloads in trusted networks)
- Legacy systems where you have no choice
When to never use MD5:
- Password storage (attackers can test 10+ billion guesses per second with GPUs)
- Digital signatures
- Any security-critical verification against an untrusted party
SHA-1 — deprecated but not dead
Output: 160 bits (40 hex characters)
SHA-1 was the successor to MD5 and was widely used through the 2000s. Google's SHAttered attack in 2017 demonstrated a practical collision — two different PDF files with the same SHA-1 hash.
Browsers stopped accepting SHA-1 TLS certificates. Git still uses SHA-1 internally for commit IDs (though it is migrating to SHA-256), but this is acceptable because git's use of SHA-1 isn't as a security primitive against adversarial attack.
When it's acceptable:
- Git commit IDs (non-adversarial context)
- Non-security checksums where MD5 is already in use and migration is hard
Never use for:
- TLS certificates (already blocked by browsers)
- Password storage
- New cryptographic work
SHA-256 — the current standard
Output: 256 bits (64 hex characters)
Part of the SHA-2 family (designed by the NSA, published by NIST in 2001), SHA-256 has no known practical weaknesses. It is the default everywhere security matters:
- HTTPS: TLS 1.3 uses SHA-256 in its handshake
- Bitcoin: each block in the blockchain is identified by double-SHA-256 of its header
- Code signing: Windows Authenticode, macOS Developer ID, and Linux package managers use SHA-256
- HMAC-SHA256: the signing algorithm behind AWS Signature V4, GitHub webhooks, and Stripe
For most new work, SHA-256 is the right choice. The output is large enough to be secure for the foreseeable future, and hardware support (AES-NI-style extensions for SHA) makes it fast on modern CPUs.
SHA-512 — bigger, sometimes faster
Output: 512 bits (128 hex characters)
SHA-512 is part of the same SHA-2 family as SHA-256. On 64-bit systems, it is sometimes faster than SHA-256 for large inputs, because SHA-512 processes 1024-bit blocks in 80 rounds vs SHA-256's 512-bit blocks in 64 rounds — and modern CPUs handle 64-bit arithmetic in a single instruction.
When to prefer SHA-512:
- When your platform is 64-bit and you're hashing large amounts of data
- Linux
/etc/shadowuses SHA-512 crypt for password hashing (though this is wrapped in a KDF, not raw SHA-512) - When you need extra collision resistance margin for long-lived signatures
The one mistake that trips up developers
Never use a bare hash for password storage.
This is the most common, most damaging error:
# BAD — do not do this
password_hash = hashlib.sha256(password.encode()).hexdigest()
A modern GPU can compute 10–20 billion SHA-256 hashes per second. With a leaked database of SHA-256 password hashes, an attacker can crack "password123" in milliseconds.
The correct approach uses a deliberately slow key derivation function:
# GOOD — use bcrypt, Argon2, or PBKDF2
import bcrypt
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
These functions are designed to take 100ms–1s per hash, which is negligible for a login but catastrophic for an attacker trying billions of guesses.
Verify a file download right now
If you want to check the SHA-256 hash of any file — a downloaded installer, a binary release, a backup — you can do it entirely in your browser without uploading the file anywhere:
Hash Generator on SnappyTools — supports MD5, SHA-1, SHA-256, and SHA-512 from text or file drag and drop. All four hashes appear simultaneously. Nothing leaves your device.
Quick reference
| Algorithm | Output | Use today? | Notes |
|---|---|---|---|
| MD5 | 128 bits | Checksums only | Broken for security |
| SHA-1 | 160 bits | Legacy only | Deprecated; collision known |
| SHA-256 | 256 bits | ✓ Yes | Default for new work |
| SHA-512 | 512 bits | ✓ Yes | Prefer on 64-bit with large data |
And the rule that overrides all of the above: never use any of these for passwords. Use bcrypt, Argon2, or PBKDF2.
Top comments (0)