Cryptographic hash functions are one of the most widely used primitives in computing — and one of the most misunderstood. They show up in password storage, file integrity checks, digital signatures, blockchain, and API authentication. Here's a practical guide to what they do, which algorithm to pick, and how to generate hashes without installing anything.
What Is a Cryptographic Hash?
A hash function takes an input of any size and produces a fixed-size output called a digest or hash. The same input always produces the same output. A tiny change to the input produces a completely different output.
Input: "hello"
SHA-256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Input: "hello!"
SHA-256: 334d016f755cd6dc58c53a86e183882f8ec14f52fb05345887c8a5edd42c87b7
Two critical properties:
- One-way — you cannot reverse a hash to get the original input (without brute force)
- Deterministic — the same input always produces the same hash
Hash functions are not encryption. Encryption is reversible with a key. Hashing is (effectively) irreversible.
The Main Algorithms
MD5
- Output: 128 bits (32 hex characters)
- Speed: Very fast
- Security: Broken — collision attacks are practical. Two different inputs can produce the same hash. Do not use for security purposes.
- Still useful for: Non-security checksums (file download verification where tampering is not a concern), legacy systems, and generating short identifiers from content.
SHA-1
- Output: 160 bits (40 hex characters)
- Speed: Fast
- Security: Broken — SHA-1 collision attacks were demonstrated in 2017 (SHAttered). Deprecated by browsers and certificate authorities.
- Still useful for: Git uses SHA-1 internally for commit hashes (though migrating to SHA-256). Not recommended for new systems.
SHA-256
- Output: 256 bits (64 hex characters)
- Speed: Fast on modern hardware with hardware acceleration
- Security: Strong — no known practical attacks
- Use for: TLS certificates, digital signatures, JWT signing (HS256), password hashing (as part of PBKDF2), file integrity, API request signing
SHA-512
- Output: 512 bits (128 hex characters)
- Speed: Slightly slower, but faster than SHA-256 on 64-bit processors for large inputs due to internal 64-bit word size
- Security: Stronger than SHA-256 — larger output, higher collision resistance
- Use for: High-security applications where output length is not a constraint
When to Use Each Algorithm
| Use Case | Recommended Algorithm |
|---|---|
| Password hashing | bcrypt, scrypt, or Argon2 (not SHA-* directly) |
| File integrity verification | SHA-256 |
| Digital signatures | SHA-256 or SHA-512 |
| API request signing (HMAC) | SHA-256 |
| Non-security checksums | MD5 or SHA-1 (acceptable for non-adversarial contexts) |
| JWT signing | SHA-256 (HS256 or RS256) |
| Blockchain/Merkle trees | SHA-256 |
Important: SHA-256 and SHA-512 are not designed for password hashing directly. They are too fast — an attacker can compute billions per second on a GPU. Use bcrypt, scrypt, or Argon2, which are intentionally slow.
How to Generate Hashes in Your Browser
Use DevZone's Hash Generator to compute MD5, SHA-1, SHA-256, and SHA-512 hashes without installing anything:
- Type or paste your input text.
- Select the algorithm (or view all at once).
- Copy the hex digest.
The tool runs entirely in your browser using the Web Crypto API — no data is uploaded to a server.
Generating Hashes in Code
JavaScript (Web Crypto API):
async function sha256(message) {
const encoder = new TextEncoder();
const data = encoder.encode(message);
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, "0")).join("");
}
const hash = await sha256("hello");
// "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
Node.js:
const crypto = require("crypto");
const hash = crypto.createHash("sha256").update("hello").digest("hex");
console.log(hash);
// "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
Python:
import hashlib
hash = hashlib.sha256(b"hello").hexdigest()
print(hash)
# "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
HMAC: Hashing with a Key
HMAC (Hash-based Message Authentication Code) combines a hash function with a secret key. The result proves both the integrity of the message and that it was produced by someone with the key.
HMAC-SHA256("message", "secret-key") → a keyed hash
HMAC is used in:
- API request signing — AWS Signature Version 4, GitHub webhook validation
- JWT signing — HS256 tokens
- TOTP — time-based one-time passwords (your authenticator app)
Without the key, an attacker can't produce a valid HMAC even if they know the algorithm and the message.
Verifying File Integrity
When you download software from the internet, the download page often shows a SHA-256 checksum. Here's how to verify it:
macOS / Linux:
shasum -a 256 downloaded-file.dmg
Windows (PowerShell):
Get-FileHash downloaded-file.exe -Algorithm SHA256
Compare the output to the checksum on the website. If they match, the file is identical to what the publisher distributed. If they differ, the file was corrupted or tampered with.
FAQ
Are MD5 hashes safe to use for anything?
For non-adversarial use cases — verifying accidental corruption, generating identifiers from content, deduplication — MD5 is fine. It's fast and compact. For anything where an attacker might try to find a collision (two inputs with the same hash), MD5 is not safe.
Can you reverse a SHA-256 hash?
Not directly. But if the input comes from a small space (like a password), an attacker can precompute hashes for every possible input (a rainbow table) and look up your hash. This is why password hashing uses salts and slow algorithms like bcrypt.
What is a salt in password hashing?
A salt is a random value added to the password before hashing. It ensures two users with the same password get different hashes, and it defeats precomputed rainbow table attacks. Bcrypt, scrypt, and Argon2 handle salting automatically.
What does "collision resistance" mean?
A hash function is collision-resistant if it's computationally infeasible to find two different inputs that produce the same hash. MD5 and SHA-1 have broken collision resistance — collisions have been found. SHA-256 has no known practical collision attacks.