How to use
Enter the key
Type or paste the shared secret into Secret key and set Key is to text, hex or Base64. Random 256-bit key creates a new secret if you are setting up signing yourself.
Add the message
Paste the exact message, such as a webhook's raw request body, or switch to the File tab and choose a file. Pick the Algorithm and Output format that your API documents.
Copy or verify
Copy the HMAC, or paste the signature you received into Verify a signature. A green notice means it matches; otherwise check the key, the exact bytes and the output format.
Why HMAC Generator
- Seven hash functions, from HMAC-SHA256 to HMAC-SHA3-512 and HMAC-MD5.
- Text, hex or Base64 keys and messages, plus files.
- Hex, Base64 and Base64URL output with a built-in signature check.
- Keys and messages never leave your browser.
Worked example: signing a webhook body
Say a shop sends this body: {"id":"evt_1042","type":"order.paid","amount":4999}, signed with the secret my-webhook-secret. Try sample loads exactly these values. With HMAC-SHA256 and hex output the result is 0e16d51af3200994cbff80aa09e145f8477191a7c0eddf328c13ff99dad87f39, and in Base64 it is DhbVGvMgCZTL/4CqCeFF+EdxkafA7d8yjBP/mdrYfzk=.
Now add a single space after the first colon, as a JSON library might when it re-formats the body. The HMAC becomes 8e8c241c5d6985ba2a4d2ed69d8aba811832d5e23b915e963b1f3b936bfc8020, with no resemblance to the first. That is why webhook handlers must sign the raw body they received, never a parsed and re-serialized copy.
HMAC algorithms and where you meet them
All of these follow the same RFC 2104 recipe; only the hash inside changes. The output length is fixed by the hash, whatever the key or message length.
| Algorithm | Hex characters | Common uses |
|---|---|---|
| HMAC-SHA256 | 64 | Webhooks from GitHub, Stripe and Shopify, AWS Signature Version 4, JWT HS256 |
| HMAC-SHA384 | 96 | JWT HS384 |
| HMAC-SHA512 | 128 | JWT HS512, some exchange and payment APIs |
| HMAC-SHA1 | 40 | OAuth 1.0 signatures, TOTP one-time codes, older webhooks |
| HMAC-MD5 | 32 | Legacy systems and some older payment gateways |
| HMAC-SHA3-256 and SHA3-512 | 64 and 128 | Newer designs that standardize on SHA-3 |
Computing the same HMAC in code
Once the values match here, the same call in your language should give the same result. Each line below signs body with key using SHA-256 and returns hex:
- Node.js: crypto.createHmac('sha256', key).update(body).digest('hex')
- Python: hmac.new(key.encode(), body.encode(), hashlib.sha256).hexdigest()
- PHP: hash_hmac('sha256', $body, $key)
- Go: h := hmac.New(sha256.New, []byte(key)); h.Write([]byte(body)); hex.EncodeToString(h.Sum(nil))
- Shell: printf '%s' "$body" | openssl dgst -sha256 -hmac "$key"
- Compare signatures with a constant-time function, such as crypto.timingSafeEqual or hmac.compare_digest, not ==.