HMAC Generator & Webhook Verifier
Compute HMAC signatures (SHA-256/512) and verify GitHub, Stripe, Slack & Shopify webhook deliveries
About HMAC Generator & Webhook Verifier
How HMAC Generator & Webhook Verifier Works
Calculates RFC 2104 / RFC 4231 Keyed-Hash Message Authentication Codes directly in your browser using the native Web Cryptography API (crypto.subtle.sign). Supports secret key encodings (UTF-8, hex, Base64), verifies provider-specific webhook signing transformations (GitHub sha256, Stripe t=,v1=, Slack v0=, Shopify Base64) using constant-time string comparison, and checks for replay-attack clock drift with zero server uploads.
HMAC Generator & Webhook Signature Verifier is an essential cryptographic utility for developers implementing or debugging Keyed-Hash Message Authentication Codes (RFC 2104 / RFC 4231) and API webhook security. Used universally across modern cloud platforms—such as GitHub, Stripe, Shopify, Slack, Twilio, and AWS SigV4—HMAC combines a shared cryptographic secret key with a message payload to verify both data integrity and sender authenticity. This tool calculates HMAC-SHA256, HMAC-SHA512, HMAC-SHA384, and HMAC-SHA1 digests with outputs in lowercase hexadecimal, uppercase hex, Base64, and Base64URL formats. It features dedicated Webhook Verifier presets that model provider-specific payload wrapping (such as Stripe's timestamp prefix 't=...,v1=...' and Slack's 'v0:timestamp:body'), tests for replay attacks with timestamp age audits, and validates incoming headers using timing-safe constant-time string comparison. All calculations execute 100% on-device using the native W3C Web Cryptography API (crypto.subtle), ensuring critical webhook secrets and customer payloads never touch an external server.
Frequently asked questions
What is an HMAC and how does it protect webhooks?+
An HMAC (Keyed-Hash Message Authentication Code) is a cryptographic hash computed using both a secret key and a message body. Because only the sender and receiver know the secret key, an attacker cannot forge or alter the webhook request in transit without invalidating the signature.
Why does Stripe include a timestamp in the signed string?+
Stripe prefixes the signature with a timestamp ('t=timestamp,v1=signature') and signs '{timestamp}.{raw_body}'. This ensures the signature cannot be intercepted and re-sent later by an attacker (known as a replay attack). Stripe SDKs automatically reject requests older than 5 minutes.
Why is my webhook signature failing to verify in backend code?+
The most common reason is re-serializing parsed JSON (e.g. JSON.stringify(req.body)) instead of verifying the raw incoming request bytes. Whitespace, key order, or character escapes differ between original bytes and serialized JSON, which produces completely different HMAC digests. Always verify against the raw byte stream.
Why should I use constant-time string comparison (timingSafeEqual)?+
Standard equality operators (like == or ===) return false immediately upon finding the first differing character. By measuring the minute fractions of a microsecond the comparison took, an attacker could theoretically guess characters in a forged signature. Timing-safe comparison takes the exact same number of operations regardless of where differences occur.
Are my secret keys or webhook payloads uploaded to any server?+
No. All calculations run strictly in your browser via window.crypto.subtle.sign(). No network calls are made and your sensitive API credentials remain 100% private.
Limitations
Verifying webhooks in production must always occur on your server; this browser tool is intended for local integration testing, debugging discrepancies, and generating test signatures.