HMAC Generator
Generate HMAC signatures with SHA-1, SHA-256, SHA-384 or SHA-512. Output as hex, base64 or base64url. All computation in your browser.
HMAC Generator Tool
How to use the HMAC generator
Paste your secret key
This is the shared secret between you and whoever you're signing data for — typically the value the API or webhook provider issued you.
Paste the message
The exact bytes you want to sign — a webhook payload, an HTTP request body, the canonical request string for AWS signature v4, etc.
Pick the algorithm
SHA-256 is the usual choice today. Use whatever the provider's documentation names: GitHub and Slack, for example, both sign with HMAC-SHA256. SHA-1 is offered for older systems that still require it.
Copy the signature
The signature is shown three ways: hex, base64 and base64url. GitHub and Slack both send hex, with a prefix (sha256= and v0= respectively); JSON Web Tokens use base64url. Copy the encoding your destination expects.
HMAC — what it is, why APIs use it
HMAC (hash-based message authentication code) combines a secret key with a message to produce a short tag. Anyone who holds the same key can recompute the tag and check that the message has not been changed; without the key it cannot be forged. It was specified by Hugo Krawczyk, Mihir Bellare and Ran Canetti in RFC 2104, published in February 1997, and works with any hash function. This page computes it with the browser's built-in Web Crypto API.
Where you will meet it
Webhook signatures are the commonest use. GitHub signs each delivery with an HMAC hex digest of the payload and sends it in the X-Hub-Signature-256 header, prefixed sha256=. Slack builds a string from a version number, a timestamp and the request body, separated by colons, takes its HMAC-SHA256 hex digest and prefixes v0=. AWS Signature Version 4 uses HMAC-SHA256 as the final step of signing a request. JSON Web Tokens signed with HS256 are HMAC-SHA256 too.
"As of today, there is no indication that attacks on SHA-1 can be extended to HMAC-SHA-1." RFC 6194 (2011)
HMAC versus a plain hash
Hashing the secret and the message together, as in SHA-256(secret + message), is not a safe substitute. With hash functions like SHA-256, an attacker who sees one such tag can extend the message and compute a valid tag for the longer version without knowing the secret. HMAC's nested construction, with the key mixed in twice, was designed to avoid this.
Key length
RFC 2104 allows keys of any length, but says that keys shorter than the hash output "is strongly discouraged as it would decrease the security strength of the function", while longer keys are acceptable but add little. In practice that means at least 32 random bytes for HMAC-SHA256 and 64 for HMAC-SHA512.
Verifying a signature
Recompute the HMAC over the exact bytes you received, before any JSON parsing changes them, and compare it with the signature using a constant-time comparison such as hash_equals in PHP, crypto.timingSafeEqual in Node.js or hmac.compare_digest in Python. An ordinary string comparison stops at the first difference, and the time it takes can leak how much of a forged signature was right. To check this page's output yourself, RFC 4231 publishes test vectors: key "Jefe" and message "what do ya want for nothing?" should give an HMAC-SHA256 beginning 5bdcc146.
RFC 2104, the providers that use it, and why HMAC-SHA1 still holds
HMAC was specified in RFC 2104 in February 1997 by Krawczyk, Bellare and Canetti.
RFC 2104 says keys shorter than the hash output are strongly discouraged; longer keys add little strength.
RFC 6194 (2011) found no indication that attacks on SHA-1 extend to HMAC-SHA-1.
GitHub signs webhooks with an HMAC hex digest in the X-Hub-Signature-256 header, prefixed sha256=.
Slack signs v0:timestamp:body with HMAC-SHA256 and sends the hex digest prefixed v0=.
AWS Signature Version 4 computes its final signature with HMAC-SHA256.
JSON Web Tokens signed with HS256 carry an HMAC-SHA256 tag, base64url-encoded.
RFC 4231 test vector: key "Jefe" and "what do ya want for nothing?" give an HMAC-SHA256 starting 5bdcc146.
Compare signatures with a constant-time function, not ==, so timing does not leak the answer.
This page uses the browser's Web Crypto API; the key and message never leave your device.
Frequently asked questions
Method & sources
How it computes
HMAC via the browser's Web Crypto API (importKey raw, sign) with SHA-1, SHA-256, SHA-384 or SHA-512 over the UTF-8 message, output as hex, base64 and base64url. An empty message is accepted and only the latest keystroke's result is shown.
What this tool implements
- The page returned nothing for an empty message (a valid HMAC input), and an earlier, slower sign() could overwrite a newer result while typing. Both fixed. Output checked against RFC 4231 test case 2 (key 'Jefe' → 5bdcc146…).
- RFC 2104 is dated February 1997; the page said 1996. RFC 2104 on key length and RFC 6194 on HMAC-SHA-1 are quoted. Slack signs with a hex digest (v0=), not base64 as the page said twice; GitHub's hex sha256= header and AWS SigV4's final HMAC-SHA256 are from their docs.
- Removed as unsourced: Razorpay, Xendit and NETS signing claims, Shopify's '24-hour overlap', 'timing attacks demonstrated in the wild', and the exact Stripe signed-payload format.
Sources
- Krawczyk H, Bellare M, Canetti R. RFC 2104: HMAC: Keyed-Hashing for Message Authentication. IETF; February 1997. https://www.rfc-editor.org/rfc/rfc2104
- Nystrom M. RFC 4231: Identifiers and Test Vectors for HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512. IETF; December 2005. https://www.rfc-editor.org/rfc/rfc4231
- Polk T, Chen L, Turner S, Hoffman P. RFC 6194: Security Considerations for the SHA-0 and SHA-1 Message-Digest Algorithms. IETF; March 2011. https://www.rfc-editor.org/rfc/rfc6194
- GitHub Docs. Validating webhook deliveries. https://docs.github.com/en/webhooks/using-webhooks/validating-web…
- Slack API. Verifying requests from Slack. https://api.slack.com/authentication/verifying-requests-from-slack
- AWS Identity and Access Management User Guide. Create a signed AWS API request (Signature Version 4). https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-re…
Pick up where you left off
Stored only in this browser — never sent to our servers.