Webhook HMAC Sign / Verify

Compute HMAC signatures for webhook bodies (Stripe, GitHub…).

Open tool

Overview

The webhook HMAC sign and verify tool computes the message-authentication signatures that webhook senders (Stripe, GitHub, Slack, Shopify, and many others) attach to their payloads. Pick the hash algorithm, paste the shared secret and the raw request body, and the tool returns the HMAC in hex or base64. The verify mode does the opposite — confirms a signature header matches a body.

Developers integrating webhooks who need to verify the request actually came from the documented sender, support engineers reproducing a customer's failed verification, and security teams auditing inbound webhook handling all need an HMAC signer/verifier. Long-tail keywords covered: verify Stripe webhook signature, compute GitHub webhook HMAC-SHA256, and check webhook payload integrity.

How it works

HMAC (RFC 2104) combines a cryptographic hash function with a shared secret to produce a fixed-length tag that anyone with the secret can verify. Webhook senders compute HMAC(secret, body) on the raw request body and attach the result as a header like X-Hub-Signature-256: sha256=... (GitHub) or Stripe-Signature: t=...,v1=... (Stripe). The receiver recomputes the HMAC with their copy of the secret and compares constant-time.

Two details bite people. The "body" must be the exact byte sequence the sender hashed — re-serialising parsed JSON drops whitespace and breaks the signature. And the comparison must use a constant-time function (crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to prevent timing attacks.

Examples

  • GitHub: HMAC-SHA256(secret, body) returns 9a4c..., attached as X-Hub-Signature-256: sha256=9a4c....
  • Stripe: signs timestamp.body with HMAC-SHA256(secret, t + "." + body), header carries t= and v1= parts.
  • Slack: signs v0:t:body with HMAC-SHA256(slack_signing_secret, ...), header is X-Slack-Signature: v0=....
  • Shopify: signs the raw body with HMAC-SHA256(secret, body) and base64-encodes the result.

FAQ

Why does parsing the JSON break my signature check?

Most parsers re-serialise to a canonical form (sorted keys, trimmed whitespace) that does not match the original bytes. Always compute the HMAC over the raw request body, before any parsing.

Should I use HMAC-SHA1 or HMAC-SHA256?

SHA-256. SHA-1 is deprecated by NIST; webhook providers that still send SHA-1 signatures usually emit a SHA-256 alternative alongside that should be preferred.

Is comparing strings with == safe?

No. Use a constant-time comparison helper to avoid leaking timing information about which byte mismatched.

What if my secret leaks?

Rotate it immediately at the sender's dashboard, update your handler, and treat any payload received during the window as untrusted. Some providers let you run two secrets in parallel during the rotation window.

Try Webhook HMAC Sign / Verify

An unhandled error has occurred. Reload ×