Hashing is one-way: easy to compute, infeasible to reverse. It powers integrity checks and password storage.
| Algorithm | Status |
|---|---|
| MD5 | ❌ Broken — collisions trivial |
| SHA-1 | ❌ Broken — deprecated |
| SHA-256 / SHA-3 | ✅ Use for integrity |
Publish a file's SHA-256 hash; recipients recompute it to verify the download wasn't tampered with.
1sha256sum installer.iso
2# compare against the vendor's published hashNever store passwords in plaintext, and never use a fast hash (SHA-256) alone for passwords — attackers can compute billions per second.
| Function | Notes |
|---|---|
| bcrypt | Battle-tested, tunable cost |
| scrypt | Memory-hard |
| Argon2id | Modern winner — memory + time hard |
These are deliberately slow and memory-intensive to thwart brute force.
A salt is a unique random value added to each password before hashing.
hash = Argon2id(password + unique_salt)
A pepper is a secret value (stored separately, e.g., in an HSM/env var) added to all passwords — so a database-only leak still can't be cracked offline.
When verifying, use constant-time comparison to avoid timing attacks. Most password libraries handle this for you — another reason not to roll your own.
An HMAC combines a hash with a secret key to verify both integrity and authenticity of a message (e.g., webhook signature verification):
HMAC-SHA256(key, message) → signature
The receiver recomputes the HMAC with the shared key; a match proves the message is authentic and unaltered.