Identity and security

SHA-256 versus HMAC: integrity, authentication and common mistakes

Understand why a plain hash cannot authenticate a message and how HMAC combines a secret key with a hash for integrity and origin checks.

8 min readUpdated 16 July 2026By

In brief

SHA-256 is an unkeyed digest. HMAC-SHA-256 uses a shared secret and a defined construction so a verifier can detect changes and authenticate possession of that key.

A digest identifies bytes; it does not identify the sender

SHA-256 deterministically maps an input to a 256-bit digest. The same bytes produce the same result, which is useful for detecting accidental changes when the expected digest is obtained through a trusted channel. Because anyone can calculate SHA-256, an attacker who changes a message can also calculate a new digest.

A plain hash therefore does not authenticate who created the message. Publishing a file and its checksum on the same compromised server does not protect users from an attacker who replaces both.

HMAC adds a secret using a reviewed construction

HMAC combines a cryptographic hash with a secret key in a construction designed for message authentication. A party that does not know the key should not be able to produce the correct tag for a modified message. The recipient recomputes the tag over the exact received bytes and compares it using a constant-time function.

Do not invent a construction such as SHA256(secret + message). Subtle issues involving length extension, ambiguity and key handling are why standardized constructions and maintained libraries exist.

  • Use a cryptographically random key of an appropriate length.
  • Keep keys out of source code, URLs, logs and browser storage.
  • Authenticate an unambiguous byte representation, including relevant headers or timestamps.
  • Compare tags with a constant-time library primitive.

Canonicalization is often the real interoperability problem

Two systems can agree on HMAC-SHA-256 and still produce different tags if they authenticate different bytes. Differences in newline style, whitespace, character encoding, header case, JSON serialization or URL encoding all matter. Define the canonical input precisely and capture it safely during testing.

For JSON webhooks, avoid parsing and reserializing the body before verification unless the protocol explicitly defines that process. Many webhook schemes authenticate the raw request bytes plus a timestamp. Follow the provider's specification exactly and test against published fixtures.

Document the authenticated input

version + "." + timestamp + "." + rawRequestBody

Know what HMAC still does not provide

HMAC does not encrypt the message; anyone who can read the transport can still read the content. It also uses a shared secret, so either party with that secret can generate a valid tag. If you need public verifiability or proof tied to a distinct private key holder, use an appropriate digital-signature design.

During troubleshooting, use a dedicated test key and synthetic payload. Never paste a production signing secret into a browser tool, even when processing is local.

Primary references

These sources support the standards and security claims in this guide. Links open on the publisher’s site.

Help improve DailyITTools?

With your permission, Google Analytics records pathname-only usage and payload-free product events. Tool inputs, outputs, query strings and inspected URLs are excluded. Privacy details