How to Calculate HMAC Signatures
Sign API requests with a shared secret, debug webhook payloads, and verify Stripe / GitHub / AWS-style signatures with the right HMAC algorithm and digest format.

More utilities that pair well with this guide:
Why this matters
Webhooks are how the cloud talks back. Stripe pings your server when a payment lands; GitHub pings when a release is cut. To prove the message is genuine, the sender includes an HMAC signature computed over the body with a shared secret. If your verifier rejects every signature, you cannot tell whether your secret is wrong, the algorithm is wrong, or the body is being tweaked by a proxy. A side-by-side HMAC tool with input previews makes the debugging cycle minutes instead of hours.
Three real scenarios
Paste the payload, the secret, and the timestamp; compute HMAC-SHA-256; compare with Stripe-Signature header.
Webhook handler ships
Build the canonical string, HMAC-sign with the shared secret, attach as a header.
API call accepted
Use the vendor's sample inputs, compute, match. If they don't match, the vendor docs are wrong.
Documentation confirmed
Walkthrough
Open the HMAC generator.
Paste the message
The exact bytes that were signed — typically the raw HTTP body. Watch out for whitespace differences.
Paste the secret key
Strings are interpreted as UTF-8 by default. Toggle "secret is hex" or "secret is Base64" if the vendor distributes binary keys.
Pick the hash algorithm
SHA-256 is the modern default; SHA-1 still appears in older systems; SHA-512 is rare but supported.
Choose the output format
Hex (lowercase) is most common for header values. Base64 is required for AWS Sig V4 and a few other APIs.
Compare with the received signature
Paste the value from the header. The tool highlights matches and mismatches character by character.
Inputs
Message: t=1731234567.{"id":"evt_123","type":"payment_intent.succeeded"}
Secret: whsec_abc123xyz
Algorithm: SHA-256HMAC-SHA-256 hex
4ed7a40c1e1f9c0bba9d7c1f24eb44a3f0bd06d0c81bd5d4a7f6cf52a6f00f1e
Power tips
- Diff the body before signing. Many webhook failures come from a proxy adding a final newline to the body. The signature is over the exact bytes — single trailing newline matters.
- Always use constant-time comparison server-side. That is your code's job, not the signing tool's. The browser tool can do plain comparison because nothing leaves the page.
- Rotate secrets without downtime by allowing two valid keys for a brief window. The tool helps you compute both signatures to confirm the new key works before retiring the old one.
- Document your canonical string. Tools like AWS Sig V4 require a specific concatenation of method, path, headers, and body hash; reproduce it manually once with the tool to confirm the formula.
Common pitfalls
Common mistake
Off by one trailing newline
The body in your IDE has a final \n; the body sent over the wire does not. Strip whitespace before signing — but strip exactly what the verifier strips.
Common mistake
The secret is interpreted as the wrong encoding
Some vendors send keys as Base64 strings; HMAC must use the decoded bytes, not the ASCII characters. Toggle the input encoding to match the vendor's docs.
Common mistake
UTF-8 BOM hides in the message
A leading byte sequence EF BB BF in the payload changes the hash. Open the source in a hex viewer if signatures repeatedly fail by an unrelated amount.
When this is the wrong tool
- Public-key signatures (RSA, ECDSA, Ed25519) — those need a different verifier. See How to Verify Digital Signatures Online.
- Symmetric encryption — HMAC authenticates, it does not encrypt. Use AES-GCM if you need confidentiality and authenticity together.
- Password hashing — never use HMAC for password storage. Use a slow KDF.
FAQ
What if my key is shorter than the block size?
HMAC handles that internally. You don't need to pad the key.
Should I sign before or after JSON formatting?
Always sign after the canonical form is fixed. If you reformat after signing, the signature breaks.
Is anything sent to a server?
No. The HMAC is computed in the browser via WebCrypto.
Next steps
- Hash the body separately first with the Hash generator when the protocol asks for
body_hash-then-HMAC. - Build the full request signature with the Parameter Signature tool.
- Decode incoming JWT signatures with the help of the Encode/Decode tool — JWTs use HMAC for HS-prefixed algorithms.