What is HMAC Generator?
HMAC Generator — An HMAC Generator is a free tool that creates Hash-based Message Authentication Codes using a secret key and a hash algorithm to verify data integrity and authenticity.
Loading your tools...
Generate HMAC-SHA256, HMAC-SHA512, HMAC-SHA1, and HMAC-MD5 signatures from a message and secret key. Verify webhook signatures from Stripe, GitHub, Slack, and Shopify. Output in hex or Base64 format. Essential for API request signing, webhook payload verification, and message authentication.
HMAC Generator: Enter a message and secret key, select a hash algorithm (SHA-256, SHA-512, etc.), and get the HMAC output instantly. Use it for API authentication, webhook verification, and message integrity checks.
The secret key is used to sign the message.
All computations happen directly in your browser. Your message and secret key never leave your device.
Supports standard algorithms like SHA-256 (standard for JWTs) and legacy MD5 for compatibility.
HMAC Generator — An HMAC Generator is a free tool that creates Hash-based Message Authentication Codes using a secret key and a hash algorithm to verify data integrity and authenticity.
Paste the exact message or webhook payload body — whitespace and encoding must match exactly.
Enter the shared secret key provided by your API service (Stripe webhook secret, GitHub secret, etc.).
Select the hash algorithm (HMAC-SHA256 is most common) and output format (hex or Base64).
Compare the generated HMAC signature with the one in your webhook header or API response.
Verifying Stripe, GitHub, Slack, and Shopify webhook signatures
Debugging API request signing for AWS Signature v4 and custom HMAC auth
Testing HMAC implementations across Node.js, Python, Go, and PHP
Validating message integrity for secure inter-service communication
HMAC (Hash-based Message Authentication Code, RFC 2104) combines a secret key with a cryptographic hash function in a specific way: HMAC(K, m) = H((K' XOR opad) ‖ H((K' XOR ipad) ‖ m)). Why not just use SHA-256(secret + message)? Because plain hashing is vulnerable to length extension attacks — if an attacker knows H(secret + message1), they can compute H(secret + message1 + padding + message2) for any message2, even without knowing the secret. HMAC's nested construction prevents this and is the only safe way to use hash functions for message authentication.
| Service | Algorithm | Header | Signed payload | Encoding |
|---|---|---|---|---|
| Stripe | HMAC-SHA256 | Stripe-Signature | timestamp + "." + raw body | hex |
| GitHub | HMAC-SHA256 | X-Hub-Signature-256 | raw body | hex (prefixed "sha256=") |
| Slack | HMAC-SHA256 | X-Slack-Signature | "v0:" + timestamp + ":" + raw body | hex (prefixed "v0=") |
| Shopify | HMAC-SHA256 | X-Shopify-Hmac-SHA256 | raw body | Base64 |
| Twilio | HMAC-SHA1 | X-Twilio-Signature | URL + sorted params | Base64 |
| AWS SigV4 | HMAC-SHA256 | Authorization | canonical request | hex |
Nine times out of ten, a webhook signature fails because the verifier hashed a parsed-and-re-serialized JSON body instead of the raw request body bytes. JSON parsing then re-serializing changes whitespace, key ordering, and number formatting — and that completely changes the HMAC. Always read the raw body: in Express, use express.raw({type: 'application/json'}) middleware on the webhook route; in Next.js API routes, read the body as a buffer before parsing; in Fastify, set rawBody: true. After verification succeeds, then parse the body.
sha256=abc...; you must compare after the "sha256=" prefixHMAC is symmetric — both sides share the same secret. Anyone with the secret can forge a signature, so it's only useful between two trusted parties (your server and a known partner). RSA / ECDSA signatures are asymmetric — the signer holds a private key, the verifier only needs the public key. This is what JWTs use (with the "RS256" and "ES256" algorithms) and what TLS certificates use. Choose HMAC for webhook authentication between trusted services (lower overhead, simpler). Choose RSA/ECDSA when you need many parties to verify without sharing a secret. See our RSA Key Generator for asymmetric signing.
When verifying a signature in your code, never use string equality (== or ===) to compare HMAC bytes — that's vulnerable to timing attacks. A naive comparison returns early on the first mismatching byte, so an attacker can measure response time to learn the signature byte-by-byte. Use language-provided constant-time comparison: Node.js crypto.timingSafeEqual(), Python hmac.compare_digest(), Ruby OpenSSL.fixed_length_secure_compare, Go hmac.Equal(). This tool's verify mode is purely for human visual inspection — production code must use constant-time comparison.