Skip to main content

Webhook Signature Validator

Verify a webhook's HMAC signature: paste the raw payload body, your signing secret and the signature from the provider's header (GitHub sha256=…, Shopify base64, or any custom HMAC-SHA1/SHA-256/SHA-512 in hex or base64), and confirm whether it matches.

Input

Must be byte-for-byte identical to what the provider signed — it is NOT trimmed or reformatted.

The secret is interpreted as UTF-8 text. It never leaves your browser or a share link.

Presets set the algorithm and encoding. Choose Custom to configure them yourself.

The value from the webhook's signature header. A sha256=/sha1=/v1=/hmac= prefix is stripped automatically.

Output

Shown once you enter a claimed signature.

The HMAC this tool computed from your payload and secret.

Was this helpful?

Guides

When a service like GitHub, Shopify, or your own backend sends a webhook, it signs the request so the receiver can prove the payload is genuine and untampered. The signature is an HMAC — a keyed hash of the raw request body computed with a shared signing secret — sent in a header such as X-Hub-Signature-256. This tool recomputes that HMAC from the same three ingredients and tells you whether it matches the signature you were sent, so you can debug a failing webhook or confirm an integration before shipping it.

How to use it

  1. Payload body — paste the exact raw request body the webhook delivered. This must be byte-for-byte identical to what the sender signed: the tool does not trim, pretty-print, or re-serialize it. Reformatting JSON (adding spaces, reordering keys) changes the bytes and will make a genuine signature fail to match.
  2. Signing secret — the secret shared between you and the provider. It's treated as UTF-8 text, stays in your browser, and is never written into a share link.
  3. Provider — pick a preset (GitHub, GitHub legacy SHA-1, or Shopify) to set the algorithm and encoding automatically, or choose Custom to select the HMAC algorithm (SHA-1, SHA-256, or SHA-512) and encoding (hex or base64) yourself.
  4. Claimed signature — paste the value from the provider's signature header. A sha256=, sha1=, v1=, or hmac= prefix is stripped automatically, so you can paste the header value verbatim.

The result reports Valid or Invalid, and the Expected signature field shows the HMAC the tool computed — handy for comparing character by character when something is off.

Hex signatures are compared case-insensitively (AB and ab are the same byte), while base64 is compared exactly. The comparison avoids exiting early on the first mismatched character.

Everything runs entirely in your browser. Your payload and secret are never sent to a server.

Why isn't there a Stripe or Twilio preset?

Because those providers don't sign the raw body. Stripe signs the string "{timestamp}.{body}" and sends it as t=…,v1=…, so you'd first reconstruct that signed string before HMAC-ing it. Twilio signs the full request URL plus the POST parameters sorted and concatenated, not the JSON body. Offering them as plain-body presets would report a false mismatch, so they're left out rather than shipped broken. You can still verify their underlying HMAC by building the signed string yourself and pasting it as the payload in Custom mode.

Why did a valid webhook still show as invalid?

Almost always because the payload bytes changed in transit or on paste. Capture the raw body before any JSON parsing or framework middleware re-serializes it, and confirm you're using the right secret and the algorithm the provider actually uses (GitHub's newer header is SHA-256; the legacy one is SHA-1).

webhooksignaturehmacverifysecuritysha256githubshopifyauthentication

Part of a workflow

All collections

Love the tools? Lose the ads.

One payment clears every ad from your account, for good. No subscription, no tracking.