HMAC Generator

HMAC is the algorithm behind most signed webhooks, AWS Signature v4 headers, and JWT HS256 tokens. Enter a message and a secret key, pick a hash family, and this generator produces the HMAC exactly as RFC 2104 specifies, useful for verifying what your backend is about to send, or reproducing a signature you received from an API.

How to compute an HMAC

  1. 1

    Paste the message

    The exact bytes to sign: a webhook payload, a canonical request, or any string.

  2. 2

    Enter the secret key

    Can be text or hex. The generator pads or hashes it to block size per the RFC.

  3. 3

    Pick the hash algorithm

    SHA-256 is the default; choose SHA-1, SHA-384, SHA-512 or MD5 for legacy compatibility.

  4. 4

    Copy the signature

    Output is lowercase hex, ready to paste into a webhook config or an Authorization header.

HMAC under the hood

HMAC wraps a plain hash function in a keyed construction so that the signature cannot be forged without the key.

The RFC 2104 recipe

HMAC(k, m) = H((k' ⊕ opad) ∥ H((k' ⊕ ipad) ∥ m))

where k' is the key padded to the hash block size, opad = 0x5c repeated and ipad = 0x36 repeated.

Algorithm choices

Algorithm Block size Output length Recommended for
HMAC-SHA-256 64 bytes 32 bytes Modern default, webhook signing
HMAC-SHA-384 128 bytes 48 bytes Higher-security API signing
HMAC-SHA-512 128 bytes 64 bytes Long-lived tokens
HMAC-SHA-1 64 bytes 20 bytes Legacy (AWS S3 v2, OAuth 1.0)
HMAC-MD5 64 bytes 16 bytes Legacy only; avoid for new work

Where HMAC shows up

  • GitHub, Stripe, Shopify webhooks: header X-Hub-Signature-256, Stripe-Signature, etc.
  • AWS Signature v4: a chain of HMAC-SHA256 over the canonical request.
  • JWT HS256: the token signature is HMAC-SHA-256(header.payload, secret).
  • Password reset tokens: HMAC over user_id + expiry + a site secret.

Common mistakes

  • Passing a hex-encoded key as text instead of decoding it to bytes first.
  • Signing the wrong payload bytes: some webhooks sign the raw request body including whitespace, others sign a canonical form.
  • Using == in JavaScript or Python to compare signatures; always use a timing-safe comparison to resist timing attacks.

Frequently Asked Questions

Almost always because the message bytes differ. Signing the JSON-parsed body introduces whitespace changes; sign the raw request body. Also verify the key is decoded the same way (hex vs raw bytes) on both sides.

Yes. If the key is shorter than the hash block size it is zero-padded; if longer, it is hashed first. RFC 2104 recommends keys at least as long as the output (32 bytes for SHA-256).

HMAC is still resistant to known MD5 collision attacks because the attack does not carry over to the HMAC construction. Still, use HMAC-SHA-256 for any new code, tooling and auditors expect it.

Yes. The message and the secret key are sent to our server over an encrypted HTTPS connection so the HMAC can be computed. They are used only for the calculation and are not stored or logged.

Related Tools

Tool available in other languages