Safeguard
Security Guides•

HMAC or a hash of key plus message for signing API requests?

Sign API requests with HMAC, not a plain hash of secret plus message. Why the shortcut is risky, what to include in the signed string, and how to verify.

Safeguard Security Team
3 min read

Sign API requests with HMAC, not with a plain hash of the secret glued to the message. HMAC is a standard keyed construction built to be safe with common hash functions. Home-made versions such as hash(secret + body) have known weaknesses, and nothing is gained by avoiding the standard tool.

Why the shortcut is tempting and risky

Writing sha256(secret + body) feels like a signature. With hash functions built the way SHA-256 is, a design like this can allow length extension: someone who sees a valid hash for a message can compute a valid hash for that message plus extra data, without knowing the secret. How much damage that does depends on how the receiver parses the data, which is a bad thing to bet on.

HMAC, defined in RFC 2104, wraps the hash twice with the key mixed in at both layers. The RFC lists its design goals: use existing hash functions unchanged, keep their speed, handle keys simply, and rest on a well-studied security analysis.

What a good signed request contains

The tag is only as good as what it covers. A typical scheme signs a canonical string made of:

  • the HTTP method
  • the path and the sorted query string
  • a timestamp
  • a hash of the body
  • any headers whose values matter

If a field is not in the signed string, an attacker can change it. If the method or path is missing, a signature for one call can be replayed against another.

Keys and verification

RFC 2104 recommends keys at least as long as the hash output and says they should be random or come from a strong generator, and refreshed periodically. Do not use a human-readable phrase as an HMAC key. Generate it with a CSPRNG and store it like any other secret.

Verify by recomputing the tag over exactly the bytes you received and comparing in constant time. Parse the body only after the tag checks out. Reject requests whose timestamp is outside a short window, and keep a short list of recent nonces if replays matter.

Ways it still goes wrong

  • Signing the parsed JSON instead of the raw bytes. Two parsers may disagree about the same text.
  • Using one key for every client. Give each integration its own key so you can revoke one without breaking the rest.
  • Truncating the tag too far. RFC 2104 allows truncation but advises keeping at least half the hash length and at least 80 bits.
  • Using a MAC where the receiver must prove who signed to a third party. Both sides hold the same key, so an HMAC cannot do that. Use a public-key signature for those cases.

Quick check

Is HMAC encryption?

No. It proves integrity and that someone with the key produced the tag. The message stays readable.

Can I use SHA-1 inside HMAC?

HMAC with an older hash is less affected than the bare hash by collision problems, but there is no reason to pick it for new work. Use SHA-256 or stronger.

Sources

Last reviewed: 19 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.