HMAC Signature Verifier (Webhooks: Stripe, GitHub, Slack)

Webhook providers sign their payloads with HMAC so you can verify the request actually came from them (not a forgery). Stripe sends Stripe-Signature with timestamp + HMAC; GitHub sends X-Hub-Signature-256; Slack uses its own version-prefixed format. This tool implements the verification for each — paste the payload, signature header, and your secret to check authenticity.

How to use the HMAC Signature Verifier (Webhooks: Stripe, GitHub, Slack)

Pick the provider. Paste the raw request body (exact bytes — Stripe / GitHub / Slack all use the unparsed body), the signature header value, and your webhook secret. The tool computes the expected HMAC and compares.

For Slack, you also need the timestamp from the X-Slack-Request-Timestamp header.

How webhook signatures prove authenticity

When a service like Stripe or GitHub calls your webhook, anyone who learns the URL could POST fake events to it. To prevent that, the provider and you share a secret; the provider computes an HMAC — a keyed hash — over the exact request body and sends the result in a header. You recompute the same HMAC with your copy of the secret and compare. A match proves the payload came from someone holding the secret and was not altered in transit.

The details differ per provider, which is where verification usually goes wrong. Stripe signs a timestamp plus the body and packs both into Stripe-Signature; GitHub sends a plain sha256= digest in X-Hub-Signature-256; Slack hashes a v0:timestamp:body string. All three sign the raw bytes, so re-serializing the JSON first breaks the check. This tool implements each format so you can confirm a signature by hand.

Common use cases

  • Debugging a failing webhook — find out whether the signature, the secret, or the body encoding is the problem.
  • Confirming you read the raw body — verify that your framework is not reparsing JSON before you hash it.
  • Checking the right secret — test a candidate signing secret against a captured payload.
  • Learning a provider format — see how Stripe, GitHub, and Slack each structure their signature header.
  • Replay awareness — inspect the timestamp providers include to defend against replayed requests.

Frequently asked questions

Why does my signature fail even with the right secret?

Almost always because the body bytes changed. Frameworks that parse JSON and re-stringify it produce different bytes than what was signed. You must hash the exact raw body the provider sent, before any parsing.

What is the timestamp for in Stripe and Slack signatures?

It is signed alongside the body so you can reject requests that are too old, which blunts replay attacks. Verify the HMAC, then check the timestamp is within a few minutes of now.

Should I compare signatures with a plain equality check?

Production code should use a constant-time comparison so an attacker cannot learn the correct signature byte by byte from timing. For a manual check in this tool that does not matter, but copy that pattern, not the plain compare, into real code.

Is HMAC the same as a digital signature?

No. HMAC is symmetric — both sides share one secret, so either can produce a valid signature. A digital signature like Ed25519 uses a private/public keypair, so only the holder of the private key can sign. Webhooks use HMAC because both parties already share a secret.
Embed this tool on your site

Free to embed, no attribution required (but appreciated). Paste this where you want the tool to appear: