Security

Webhook Signature Verifier

Verify webhook signatures from Stripe, GitHub and other providers, and diagnose mismatches.

Last reviewed by the Radiatus Cloud team

Match
—

Computed Signature

Need this handled by experts?

Radiatus runs VAPT, managed SOC & security engineering for regulated teams.

Book a free security consult

Verify against the raw body

Providers sign the exact bytes they sent. Most frameworks parse JSON before your handler runs, and re-encoding it changes whitespace, key order and Unicode escaping, so the recomputed HMAC covers different bytes and never matches. Capturing the raw payload before any body-parsing middleware is the fix, and this single issue accounts for the majority of signature failures against otherwise correct code.

Each provider builds the signed string differently

Stripe signs a timestamp, a dot, and the payload, and sends multiple signatures in one header for key rotation. GitHub signs the body alone and prefixes the header value with sha256=. Others sign a concatenation of method, path, timestamp and body. Copying verification code between providers without reading their specification produces valid-looking failures.

Constant-time comparison

Comparing the computed and received signatures with ordinary string equality leaks information through timing, because comparison exits at the first differing byte. Every platform ships a constant-time comparison; the substitution is one line.

Timestamp tolerance stops replay

A captured valid request stays valid indefinitely unless the timestamp is checked. Reject anything outside roughly five minutes, and record processed event IDs so a duplicate delivery becomes a no-op — which also gives you the idempotency that at-least-once delivery requires.

Encoding and secret mistakes

Signatures may be hex or base64, and comparing one form against the other always fails. Secrets are often supplied with a prefix such as whsec_, and providers differ on whether the prefix is part of the key. A trailing newline from an environment file is another silent cause.

Related tools

  • Password Strength Checker — Measure password strength by entropy and pattern analysis rather than character-class rules. Checked entirely in your browser.
  • Password Generator — Generate strong random passwords and passphrases in your browser using the Web Crypto API. Nothing is transmitted, logged or stored.
  • Hash Generator — Generate MD5, SHA-1, SHA-256 and SHA-512 hashes in your browser. Compare checksums and verify file integrity with nothing uploaded to a server.
  • Base64 Encoder/Decoder — Encode and decode Base64 in your browser, including URL-safe Base64 and UTF-8 text. Handles files and data URIs locally with nothing uploaded.

Frequently Asked Questions

Why does my webhook signature never match?

Almost always because the body was parsed and re-serialised before verification, changing whitespace or key order. Sign and verify the raw bytes.

Can I reuse verification code across providers?

No. Stripe signs a timestamp plus payload, GitHub signs the body alone with a sha256= prefix, and others sign method, path and timestamp too.

Why must comparison be constant time?

Because ordinary string equality exits at the first differing byte and leaks information through timing. Every platform provides a constant-time function.

How do I prevent replay attacks?

Reject requests whose signed timestamp is outside about five minutes, and record processed event IDs so duplicates become no-ops.

Privacy & Security

Computed locally in your browser using WebCrypto. No data is sent to any server.

Data: None
Client-side-Side
Active
v1.0

How to Use

Paste payload, secret, and signature to verify.

Disclaimer: This tool is provided "as is" without warranty of any kind. Results are for educational and utility purposes.