Safeguard
Application Security•

What is a message authentication code (MAC) and how does HMAC work?

A MAC proves a message came from a holder of a shared key and was not altered. See how HMAC and CMAC work, how MACs differ from signatures, and pitfalls.

Safeguard Security Team
4 min read

A message authentication code, or MAC, is a short tag computed from a message and a secret key. A receiver who holds the same key recomputes the tag. If it matches, the message came from someone with the key and was not altered. A MAC gives integrity and authenticity, not secrecy.

How is a MAC different from a hash or a signature?

A plain hash has no key, so anyone can recompute it. If an attacker changes a message, they can change the hash too. A MAC prevents that because forging a tag requires the key.

A digital signature uses a key pair. Anyone with the public key can verify, and only the holder of the private key can sign. A MAC uses one shared key, so both parties can create tags. It is faster and simpler, but it cannot prove to a third party which side produced a message.

What is HMAC?

RFC 2104 describes HMAC as a mechanism for message authentication using cryptographic hash functions, usable with any iterative hash function in combination with a secret shared key. It notes that the cryptographic strength of HMAC depends on the properties of the underlying hash function. NIST FIPS 198-1 standardises HMAC for US federal use, defining it as a keyed hash message authentication code that works with an approved hash function and a shared secret key.

You do not build HMAC by hashing key plus message. The standard construction is specific, and naive versions have known weaknesses with some hash designs. Use a library function named HMAC.

What is CMAC?

NIST SP 800-38B specifies CMAC, a MAC based on a symmetric key block cipher. It can provide assurance of the authenticity and so the integrity of binary data. Choose it where a block cipher is already available and a hash function is not, such as some constrained devices.

Where are MACs used?

  • Webhook signatures, where a service signs each request body with a secret
  • Signed cookies and tokens that prove a server issued them
  • Network protocols such as TLS, where record integrity is protected
  • Key derivation and message framing in many protocols
  • Integrity checks on stored data in tamper evident formats

What mistakes should you avoid?

Comparing tags with a normal equality test. Early exit comparison can leak how many leading bytes were right through timing. Use the constant time comparison your library provides.

Reusing one key for several purposes. Derive separate keys for separate uses.

Skipping replay protection. A valid tag on an old message is still valid. Include a timestamp or counter inside the authenticated data and reject stale ones.

Authenticating the wrong bytes. Verify the exact raw bytes received, not a re-serialised copy, because different serialisations of the same data give different tags.

Weak keys. Generate keys from a cryptographic random source and store them in a secrets manager.

A constructed example

A payment partner posts webhooks to your server and includes a header with an HMAC tag of the body, computed with a shared secret. Your handler reads the raw body, computes the HMAC with the secret, compares it to the header in constant time, and checks that a timestamp in the body is under five minutes old. A request with a wrong tag or an old timestamp is rejected and logged.

Had the handler parsed the JSON and re-encoded it before verifying, a harmless difference in key order would break valid requests. Had it used a normal string comparison, it would leak timing information.

How to check or apply this

  1. Find every place your code verifies a tag, signature or token.
  2. Confirm the algorithm is HMAC or CMAC from a maintained library, with an approved hash such as SHA-256.
  3. Verify the raw received bytes.
  4. Use constant time comparison.
  5. Add a timestamp or nonce and enforce a freshness window.
  6. Use a separate key per purpose and per partner, and rotate them.
  7. Log failures without logging the secret or the full tag.

Quick check

Does a MAC encrypt the message?

No. The message stays readable. If you need secrecy as well, use authenticated encryption or encrypt and then apply a MAC.

Can I use a MAC instead of a digital signature?

When both sides trust each other and share a key, yes. If a third party must verify who signed, you need a signature.

Sources

Last reviewed: 18 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.