Webhook Signature Verifier
Compute the expected webhook signature for Stripe, GitHub, Slack, Shopify or a generic HMAC-SHA256 scheme from the secret and raw body, and compare it with the one you received.
Free · No sign-up · Your inputs stay in your browser
Input
Compute and verify a webhook signature
Output
Expected signature
Stripe signs `${timestamp}.${body}` with HMAC-SHA256 and may send several v1 values during secret rotation; any one matching is valid. Reject timestamps more than five minutes old to stop replays. The usual bug is verifying a body the framework already parsed and re-serialised: read the raw bytes (request()->getContent() in Laravel, express.raw() in Express) and compare in constant time (hash_equals, crypto.timingSafeEqual).
Runs in this browser. Nothing you paste is sent to a server.
About this tool
Method, assumptions, practical next steps, and limits.
The bug is almost always the body
The signature covers the exact bytes the provider sent. Frameworks parse JSON before your handler runs, and re-encoding it changes whitespace and key order, so the HMAC never matches. Read the raw body: $request->getContent() in Laravel, express.raw() on the route in Express. Then compare with a constant-time function such as hash_equals or crypto.timingSafeEqual. Stripe's manual verification guide spells out its scheme.
Timestamps stop replays
Stripe and Slack sign a timestamp with the body. Reject signatures older than about five minutes, or an attacker who captured one request can replay it later.