WebTool

Crypto & Security · Ch. 2

HMAC Explained: A Hash with a Key, for Tamper-Proof, Authenticated Messages

WebTool Team · Published 2026-09-08 · HMAC / Signing / Security / API

HMAC = a hash computed with a secret key mixed in. A raw hash can only verify "the data wasn't corrupted"; HMAC also proves "the data came from the key holder" — which is why it's the de facto standard for API request signing. Verify it hands-on with our HMAC calculator.

Why HMAC is needed

An open API usually has to answer two questions:

  1. Were the request parameters left unchanged in transit? (Integrity)
  2. Was the request really sent by a legitimate client? (Authenticity)

A raw hash(params) only answers question 1 — an attacker who modifies the parameters can simply recompute the hash. HMAC mixes a shared secret into the computation, so an attacker without the key cannot forge a valid signature. Both questions are solved at once.

Why not hash(key + message) directly

That naive concatenation is vulnerable to length-extension attacks: the Merkle–Damgård structure of MD5/SHA-1/SHA-2 lets an attacker append data to the original message and compute a valid new hash without knowing the key. HMAC's two-layer construction, H((k⊕opad) || H((k⊕ipad) || message)), closes exactly this hole. Hand-rolling your own key+message scheme is a high-risk reinvention — always use standard HMAC.

The standard API signing recipe

stringToSign = method + "\n" + path + "\n" + sortedParams + "\n" + timestamp + "\n" + nonce
signature    = HexHMACSHA256(stringToSign, secretKey)
  • Sort parameters before signing, so ordering differences don't break verification.
  • Include a timestamp and enforce freshness (e.g. 5 minutes) to prevent long-term replay.
  • Include a one-time nonce or request ID to block short-term replay.
  • Compare signatures with a constant-time comparison — byte-by-byte comparison leaks timing information.

Common misuses

  • Treating HMAC as encryption: a signature doesn't hide content — parameters travel in plaintext, so confidentiality still requires HTTPS.
  • Hardcoding the secret into frontend code: a key in the browser is effectively public; browser-side signing needs a different design (e.g. temporary credentials).
  • Using MD5/SHA-1 for HMAC: although the HMAC construction mitigates many of their weaknesses, new systems should go straight to HMAC-SHA-256.

Last updated: 2026-09-08