dev

Hash vs HMAC for Checksums and API Signatures

Decide when to use a hash, when to use HMAC, and how to check algorithms, encodings, keys, signatures, JWT inspection, webhooks, and secret-handling risks.

A hash and an HMAC can both produce a long hexadecimal-looking string, but they answer different questions. A hash answers “did this input produce this digest?” An HMAC answers “did someone with the shared secret produce this digest for this message?” If you choose the wrong one, a checksum can be mistaken for authentication.

Use a plain hash for non-secret integrity checks

Use a hash generator when the goal is repeatable comparison. The same input and the same algorithm produce the same digest. That makes hashes useful for file checksums, cache keys, deduplication, content fingerprints, and checking whether copied text changed.

This does not prove who created the input. Anyone with the same text can compute the same hash. If a public webhook body is hashed with SHA-256 but no secret is involved, an attacker can also compute a matching digest after changing the body. The digest may detect accidental corruption, but it does not authenticate the sender.

Algorithm choice matters. MD5 and SHA-1 still appear in older file-check workflows, but they should not be used as new security boundaries. For modern integrity comparisons where you control the choice, SHA-256 is usually a safer default. If you are matching a vendor-provided checksum, use the algorithm the vendor publishes and compare the exact encoding they provide.

Use HMAC when the receiver must verify a shared secret

Use an HMAC generator when the verification includes a secret key. HMAC combines a message, a hash function, and a secret key into a keyed message authentication code. The receiver recomputes the HMAC with the same message and secret; if the result matches, the receiver has evidence that the sender knew the secret and that the message was not changed after signing.

This is why HMAC is common in webhook signatures and API request signing. A payment provider, deployment platform, or internal service can sign the request body. Your server can recompute the signature using the shared secret and compare it before trusting the event.

HMAC is not encryption. The message remains readable unless a separate transport or encryption layer protects it. HMAC verifies authenticity and integrity; it does not hide the content.

Debug the exact bytes, not just the visible text

Signature mismatches often come from input differences, not from the algorithm itself. The sender may sign the raw request body, while your code signs a parsed and re-serialized JSON object. Those bytes are not guaranteed to match. Whitespace, property order, newline style, character encoding, and escaping can all change the byte sequence.

When debugging an API signature, capture the raw body exactly as received. Confirm the algorithm, such as HMAC-SHA256. Confirm the key format: plain text, hex, Base64, or a platform secret string. Confirm the output encoding: hex digest, Base64, or a header value with a prefix such as `sha256=`. Compare the same representation on both sides.

If the provider signs a timestamp plus body, include the timestamp exactly as specified. If the signature header includes multiple versions or multiple signatures, compare the documented one. Small formatting differences are enough to produce a completely different HMAC.

Do not reverse hashes or decode signatures

A hash is one-way for practical use. A tool may compare known inputs with known hashes, but it does not “decode” a secure digest back into the original message. Treat claims about reversing modern hashes with caution unless the input space is tiny or already known.

An HMAC output is also not something to decode. You verify it by recomputing with the same message and secret, then comparing safely. If the values differ, the cause is usually the wrong secret, wrong input bytes, wrong algorithm, wrong encoding, or a changed message.

JWT decoding is inspection, not verification

JWT workflows create another common confusion. Use JWT Decoder to inspect the header and payload, but decoding only reads Base64URL-encoded JSON. It does not prove the token is valid. Signature verification requires the correct algorithm, key, issuer rules, audience rules, and expiration checks in the system that owns the trust decision.

If you only need to understand what claims a token contains, decoding is fine. If you need to accept a login, authorize an API call, or trust a webhook-like token, decoding alone is not enough.

Secret handling rules for browser checks

Browser tools are useful for learning, comparing sample values, and debugging non-production examples. Do not paste production API secrets, webhook signing keys, password reset tokens, or customer credentials into a browser tool. Use synthetic secrets such as `test_secret_123`, keep the same encoding shape, and reproduce the mismatch with safe data.

For internal runbooks, record the algorithm, signed input construction, key source, output encoding, and comparison rule. That makes future signature failures faster to debug and reduces the chance that someone treats a hash as an HMAC or an HMAC as encryption.

Decision checklist

  • Need to compare two non-secret values? Use a hash.
  • Need to prove the sender knew a shared secret? Use HMAC.
  • Need confidentiality? Use encryption in addition to transport security; HMAC does not hide content.
  • Need to inspect JWT claims? Decode the token.
  • Need to trust a JWT? Verify the signature and claims in the backend.
  • Signature mismatch? Check raw input bytes, algorithm, key format, output encoding, and header format.

FAQ

Is HMAC the same as encryption?

No. HMAC authenticates a message with a shared secret. It does not hide the message content.

Can I use MD5 for API signatures?

Avoid MD5 for new security-sensitive designs. If an existing API requires a legacy algorithm, follow that API only for compatibility and avoid using it as a model for new systems.

Why does my HMAC result not match the provider header?

The most common causes are signing parsed JSON instead of raw body bytes, using the wrong secret format, choosing the wrong algorithm, or comparing hex output with Base64 output.

Can a hash prove who sent a message?

No. A plain hash has no secret. Anyone who knows the input and algorithm can compute the same digest.

Continue reading