Cryptographic hashes appear in password storage, file verification, API authentication, digital signatures, and blockchains. Here's how they work and which one to use for each purpose.
What is a cryptographic hash?
A hash function takes input of any length and produces a fixed-length output. The key properties:
- Deterministic: The same input always produces the same hash.
- One-way: You cannot reverse a hash to get the original input.
- Avalanche effect: A small change in input produces a completely different hash.
- Collision-resistant: It should be computationally infeasible to find two different inputs that produce the same hash.
A hash generator lets you compute MD5, SHA-1, SHA-256, and SHA-512 from text or files instantly in the browser.
MD5 (128-bit / 32 hex chars)
``
MD5("hello") = 5d41402abc4b2a76b9719d911017c592
`
Status: Cryptographically broken. MD5 is vulnerable to collision attacks — it's possible to find two different inputs with the same MD5 hash in milliseconds with modern hardware.
Use it for: Non-security checksums (detecting accidental corruption), legacy system compatibility, cache keys, non-sensitive data fingerprinting.
Do NOT use it for: Password hashing, digital signatures, security-critical file verification.
SHA-1 (160-bit / 40 hex chars)
<code>
<p>SHA-1("hello") = aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d</p>
</code>
Status: Cryptographically weak. SHA-1 collision attacks have been practically demonstrated (SHAttered, 2017). Major certificate authorities and Git (for new repos) have moved away from SHA-1.
Use it for: Legacy compatibility only. Old Git commits still use SHA-1. Avoid for new systems.
SHA-256 (256-bit / 64 hex chars)
<code>
<p>SHA-256("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824</p>
</code>
Status: Current standard. No known practical attacks. Part of the SHA-2 family (also includes SHA-384, SHA-512).
Use it for: File integrity verification, digital signatures, API request signing, blockchain transactions, HMAC keys, everywhere SHA-1 was used.
SHA-512 (512-bit / 128 hex chars)
<code>
<p>SHA-512("hello") = 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043...</p>
</code>
Status: Even more resistant than SHA-256. The output is longer (better for collision resistance) but computationally slightly more expensive.
Use it for: When SHA-256 isn't strong enough (extremely high-security scenarios, long-term archival integrity). The extra strength is rarely necessary for most applications.
HMAC: Keyed Hashing
HMAC (Hash-based Message Authentication Code) combines a secret key with the hash to authenticate both data integrity and identity.
<code>
<p>HMAC-SHA256(key, message) = a unique hash per key+message pair</p>
</code>
Uses: API authentication (signing requests), JWT validation (HS256), webhook verification, session tokens.
How it works:
<code>
<p>HMAC(K, m) = H((K' XOR opad) || H((K' XOR ipad) || m))</p>
</code>
In practice, you use a library:
<code>javascript
<p>// Node.js</p>
<p>const crypto = require('crypto');</p>
<p>const hmac = crypto.createHmac('sha256', secretKey);</p>
<p>hmac.update(message);</p>
<p>const signature = hmac.digest('hex');</p>
</code>
<code>python
<p>import hmac, hashlib</p>
<p>signature = hmac.new(secret_key.encode(), message.encode(), hashlib.sha256).hexdigest()</p>
</code>
Password hashing: don't use SHA
SHA algorithms are fast — by design. This makes them terrible for password hashing, because an attacker can compute billions of SHA hashes per second on a GPU.
Use purpose-built password hashing algorithms:
- bcrypt: Adaptive cost factor, resistant to GPU attacks. Standard for most web apps.
- Argon2: Winner of the Password Hashing Competition (2015). Three variants: Argon2i (side-channel resistant), Argon2d (GPU resistant), Argon2id (both). Recommended for new systems.
- scrypt: Memory-hard algorithm. Widely used (Litecoin, OpenSSL).
`python
Python: bcrypt
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
is_valid = bcrypt.checkpw(password.encode(), hashed)
Python: Argon2
from argon2 import PasswordHasher
ph = PasswordHasher(time_cost=3, memory_cost=65536, parallelism=1)
hashed = ph.hash(password)
is_valid = ph.verify(hashed, password)
`
<code>javascript
<p>// Node.js: bcrypt</p>
<p>const bcrypt = require('bcrypt');</p>
<p>const hash = await bcrypt.hash(password, 12);</p>
<p>const valid = await bcrypt.compare(password, hash);</p>
</code>
File verification
Verifying a downloaded file is intact:
`bash
Linux/macOS
sha256sum downloaded-file.iso # Compute hash
echo "expected_hash downloaded-file.iso" | sha256sum --check # Verify
macOS (alternative)
shasum -a 256 downloaded-file.iso
Windows (PowerShell)
Get-FileHash downloaded-file.iso -Algorithm SHA256
`
In Python:
`python
import hashlib, sys
def file_hash(path, algorithm='sha256'):
h = hashlib.new(algorithm)
with open(path, 'rb') as f:
while chunk := f.read(65536):
h.update(chunk)
return h.hexdigest()
print(file_hash('large-file.iso'))
``
Choosing the right hash function
| Use case | Recommended |
|----------|-------------|
| File integrity check (non-security) | MD5 or SHA-256 |
| File integrity check (security) | SHA-256 |
| Digital signatures | SHA-256 or SHA-512 |
| API request signing | HMAC-SHA256 |
| JWT tokens | HMAC-SHA256 (HS256) or RSA-SHA256 (RS256) |
| Password storage | Argon2id or bcrypt |
| Blockchain | SHA-256 (Bitcoin), Keccak-256 (Ethereum) |
| UUID generation | Not a hash — use crypto.randomUUID() |
Never use MD5 or SHA-1 for anything security-sensitive. SHA-256 covers most needs; add HMAC when you need authentication alongside integrity.
Originally published at https://snappytools.app/hash-generator/