Hashing, HMAC and encryption are three different things
What each one is for, which of them you can reverse, and why MD5 still has a legitimate use.
Last reviewed 8 September 2026
Hashing, HMAC and encryption get used interchangeably in conversation and they solve different problems. Choosing the wrong one produces code that looks secure and is not. The distinction is simple enough to state in a table and worth understanding properly.
| Hash | HMAC | Encryption | |
|---|---|---|---|
| Reversible | No | No | Yes, with the key |
| Needs a key | No | Yes | Yes |
| Answers | Has this changed? | Who sent this, and has it changed? | Can anyone else read this? |
Hashing: a fingerprint, not a container
A hash function turns any input into a fixed-length digest. The same input always produces the same digest, and changing a single bit produces a completely different one. Crucially, there is no inverse operation: the digest does not contain the input in some scrambled form, so there is nothing to recover.
That makes hashes good for detecting change — verifying a download, spotting duplicate files, indexing content — and useless as storage for anything you need back.
When a website appears to “reverse” an MD5 hash, it is not reversing anything. It has hashed billions of common inputs and is looking yours up. That works for password123 and fails completely for anything unpredictable.
Which hash, and when
- MD5 and SHA-1 are broken for security purposes. Researchers can construct two different inputs with the same digest, so neither can prove a file has not been tampered with by someone who intended to. They remain perfectly fine for detecting accidental corruption in a transfer, which is why some projects still publish MD5 checksums.
- SHA-256 and SHA-512 are the current general-purpose choices with no practical attacks.
- bcrypt, scrypt and Argon2 are for passwords specifically. They are deliberately slow, which is a feature: it turns an attacker’s billions of guesses per second into thousands.
That last point is the one most often missed. SHA-256 is an excellent hash and a bad way to store passwords, precisely because it is fast.
HMAC: a hash that proves who
A plain hash proves nothing about origin, because anyone can compute one. If a message and its hash both travel over the same channel, an attacker who alters the message simply recomputes the hash.
An HMAC mixes a secret key into the hashing process. Only someone holding the key can produce a valid value, and only someone holding it can verify one. That is the mechanism behind signed webhooks: the sender computes an HMAC over the payload, and you recompute it with the shared secret to confirm both that it came from them and that nothing changed on the way.
The most common failure when implementing this is subtle. The signature covers the exact bytes that were sent. If your framework parses the JSON body and you re-serialise it before hashing, key order or whitespace can differ and the signature will not match even though the content is identical. Always hash the raw body. You can reproduce the expected value with the HMAC generator to see which side is wrong.
Encryption: reversible, on purpose
Encryption transforms data so that only a holder of the key can read it, and it is designed to be reversed. That is the entire difference from hashing, and it determines when you use it: encryption is for things you need to read again, hashing is for things you never do.
Two properties matter when choosing a scheme.
Authenticated encryption
Older modes such as CBC provide confidentiality but not integrity. An attacker who cannot read the ciphertext may still be able to modify it in ways that produce meaningful changes in the plaintext. Authenticated modes such as AES-GCM attach a tag that makes decryption fail if a single bit has been altered. Prefer them.
Key derivation
A passphrase is not a key. Turning one into a key requires a deliberately slow derivation function — PBKDF2, scrypt or Argon2 — with a random salt, so that an attacker holding the ciphertext cannot simply try dictionary words at speed. A scheme that feeds a passphrase directly into a fast hash to produce a key is a weak scheme regardless of the cipher it then uses.
The text encryption tool here uses PBKDF2-SHA256 to derive an AES-256-GCM key with a fresh random salt and initialisation vector per message, and it states those parameters on the page so you can judge them rather than trust them.
Choosing correctly
- Storing passwords? Argon2, scrypt or bcrypt. Never a plain hash, however modern.
- Verifying a download? SHA-256 published by the project over a channel you trust.
- Verifying a webhook? HMAC-SHA256 over the raw body, compared in constant time.
- Protecting a message someone must read later? Authenticated encryption with a properly derived key.
- Making data safe to put in a URL? That is encoding, not security. Base64 hides nothing.
And the rule that covers the rest: do not implement your own scheme. Use your platform’s vetted implementation. The failures in real systems are almost never broken ciphers — they are reused initialisation vectors, keys in source control, missing authentication and comparisons that leak timing.