HMAC Generator
Runs in your browserSign a message with a shared secret using HMAC-SHA256, SHA-384, SHA-512 or SHA-1. Computed with WebCrypto in your browser.
About this tool
HMAC answers a question a plain hash cannot: not just 'has this data changed?' but 'was this data produced by someone who knows the secret?'. That is why every webhook provider — Stripe, GitHub, Slack — signs its payloads with HMAC and expects you to recompute the signature before trusting the request. This tool performs the same computation locally so you can check a signature by hand while debugging, or generate one for a request you are constructing.
How to use
- Paste the message or payload exactly as it will be transmitted — whitespace matters.
- Enter the shared secret.
- Pick the hash the other side uses; SHA-256 is by far the most common.
- Compare the signature against the one in the request header.
When to use this tool
- Debugging why a webhook signature check is failing.
- Signing an API request that requires HMAC authentication.
- Verifying that a payload you received really came from the expected sender.
- Reproducing a signature from documentation to confirm your implementation.
Tips
- Signature mismatches are almost always caused by the message body differing — a re-serialised JSON payload is not byte-identical to the original.
- Most providers publish the signature in hex, which is what this tool outputs; a few use base64.
- HMAC-SHA1 is still widely deployed and is acceptable here, because HMAC does not rely on the hash being collision-resistant.
Limitations
- Your secret is used in the browser and never transmitted, but avoid pasting production secrets into any web page, including this one.
FAQ
- Is my secret sent anywhere?
- No. The key is imported into WebCrypto in your browser and the signature is computed locally. Nothing is transmitted or stored.
- Should I paste a production secret here?
- Prefer not to — as a habit, not because of this page specifically. Use a test secret where you can. Any secret pasted into any web page has been in a browser's memory and possibly its clipboard history.
- Why doesn't my signature match the provider's?
- Nine times out of ten the message differs. Sign the raw request body exactly as received, before any parsing or re-serialising, and check whether the provider expects a prefix such as a timestamp joined to the payload.