HMAC Calculator

Generate HMAC-SHA256 signatures for webhooks and APIs — or paste one to verify it. 100% client-side: your secret never leaves this browser.

Your secret key never leaves your device — all computation happens in your browser.

Computed with the WebCrypto API inside your browser — your secret and message are never uploaded anywhere, so there is nothing to delete. Tip: use test-mode secrets while debugging.

What is HMAC? (Hash-based Message Authentication Code)

HMAC (Hash-based Message Authentication Code) is how two systems prove a message is genuine without sharing anything except a secret key. The sender computes HMAC(secret, message) and attaches the resulting signature; the receiver recomputes it with the same secret. If the two signatures match, the message is authentic and unmodified — no eavesdropper or tamperer in the middle can forge it without the secret.

That one property makes HMAC the workhorse of webhook security. When Razorpay, Stripe or GitHub POSTs an event to your server, the signature in the header is an HMAC of the payload. Your server recomputes it — match means the event really came from them; mismatch means reject it. An HMAC calculator lets you perform that computation by hand while you are building or debugging the integration, instead of guessing why your server keeps saying "invalid signature".

How to generate an HMAC signature

Generating a signature takes three inputs: the message (exactly the bytes being signed — for a webhook, the raw request body), the secret key (the shared secret, never the public key), and the algorithm (usually HMAC-SHA256). This page computes it with the WebCrypto API directly in your browser — the same standardized cryptography your browser uses for HTTPS — and shows the result in hex, base64 and base64url, because different APIs expect different encodings.

The most common mistake at this step is signing the wrong bytes. If you are debugging a webhook and the signature never matches, the odds are overwhelming that your server hashed a parsed-and-reserialized JSON body instead of the raw bytes that arrived over the wire. Whitespace, key order and Unicode escapes all change the bytes, and HMAC signs bytes, not objects. Paste the exact raw payload into the message box here and compare against what your server computed — the difference will show itself.

How to verify an HMAC signature

Verification is generation plus a comparison: recompute the signature for the message and secret you have, then check it against the signature you received. Paste the received signature into the "Verify against" box and this page renders a verdict — green match or red mismatch with the usual suspects listed (wrong secret, altered message bytes, wrong algorithm, hex-vs-base64 confusion).

One honest caveat: this verify mode is a debugging aid, not production security code. In your server, always compare signatures with a constant-time function (crypto.timingSafeEqual in Node, hmac.compare_digest in Python) — a plain === leaks timing information that can theoretically help an attacker guess the signature byte by byte. The browser cannot do much better than string comparison, which is fine for debugging your own integration but not for guarding production traffic.

Webhook signature verification

The pattern is the same across providers: the service signs the raw request body with your webhook secret and puts the signature in a header — X-Razorpay-Signature, Stripe-Signature, X-Hub-Signature-256 for GitHub. Your endpoint recomputes HMAC-SHA256 over the raw body and compares. To debug a failing webhook locally, copy the raw body from your server logs (log it before any JSON parsing), paste it here with your webhook secret, and see whether the output matches the header you received. If it matches here but not on your server, the bug is in how your server reads the body — the classic Express mistake is letting express.json() parse the body before your verification middleware sees the raw bytes.

Razorpay signatures: webhook vs payment

Razorpay has two different signatures, and mixing them up is the single most common Razorpay integration bug. They use different secrets, different messages, and arrive in different places:

  • Webhook signature: HMAC-SHA256(webhook_secret, raw_request_body) → hex, delivered in the X-Razorpay-Signature header. The webhook secret is set in the Razorpay Dashboard where you configure the webhook — it is not your API key secret.
  • Payment (checkout) signature: HMAC-SHA256(key_secret, razorpay_order_id + "|" + razorpay_payment_id) → hex, returned by Checkout as razorpay_signature. This one uses your API key secret.

The preset buttons above configure the tool for each case: the webhook preset sets SHA-256 and reminds you the message must be the raw body; the payment preset fills the order_id|payment_id template so you just replace the two IDs. Both formulas are per Razorpay's documented behavior — if Razorpay ever changes them, their docs are the authority, not this page.

HMAC vs plain hashing

A plain hash like SHA-256 is a fingerprint anyone can compute — it proves a message has not changed since the hash was made, but says nothing about who made it. HMAC folds a secret key into the computation, so a valid HMAC proves two things: the message is unmodified and it came from someone holding the secret. That is why APIs sign with HMAC instead of plain hashes: a hash on a webhook proves nothing, because an attacker can recompute it after modifying the payload. Without the secret, they cannot forge the HMAC.

HMAC algorithms: which one to pick

Always use what your provider specifies — this is not a choice you get to make independently, since both sides must agree. In practice that means HMAC-SHA256 for Razorpay, Stripe, GitHub and most modern APIs. SHA-512 is stronger and fine where supported, but produces longer signatures; SHA-1 is legacy — it survives in old integrations but should not be chosen for anything new. The calculator supports all four so you can match whatever the other side expects.

How it works

1

Enter the message

Paste the exact bytes to sign — for a webhook, the raw request body, copied before any JSON parsing touches it.

2

Enter the secret

Type your secret key. If it was given to you as hex or base64, switch the key format so it is decoded correctly.

3

Pick the algorithm

Choose the HMAC variant your API expects — usually HMAC-SHA256. Or tap a Razorpay preset to prefill everything.

4

Generate & verify

Hit Generate, copy the signature in hex, base64 or base64url — and optionally paste a received signature to get a match/mismatch verdict.

Tips

  • Sign bytes, not objects. The number-one HMAC debugging rule: hash the exact raw bytes. Re-serializing JSON changes whitespace and key order and breaks the signature.
  • Match the encoding. Razorpay webhooks use lowercase hex; other APIs use base64. A correct signature in the wrong encoding looks like a mismatch — check the docs.
  • Test secret vs live secret. The second most common mismatch: verifying a test webhook with the live secret or vice versa. They are different secrets.
  • Watch trailing newlines. A stray newline at the end of a pasted payload changes the HMAC. Paste carefully; the verify box trims surrounding whitespace on the signature, not the message.
  • Use test-mode secrets here. The computation never leaves your browser, but good hygiene is good hygiene — debug with test secrets when you can.
  • Server code needs constant-time comparison. This page's verify is for debugging. Production endpoints must use timingSafeEqual / compare_digest, not ===.

Common uses

  • Debugging Razorpay webhooks — recompute the expected signature by hand and find where your server diverges.
  • Verifying Razorpay checkout payments — check the order_id|payment_id signature before capturing funds.
  • Stripe webhook debugging — Stripe signs with HMAC-SHA256 too; same workflow, different header.
  • GitHub webhook secrets — verify X-Hub-Signature-256 payloads while setting up CI triggers.
  • API request signing — many REST APIs authenticate requests with an HMAC of the method, path and timestamp.
  • Learning cryptography — see exactly how message, secret and algorithm combine into a signature.

Frequently asked questions

Is HMAC Calculator free to use without signup?

Yes. EzySize’s HMAC Calculator tool is free to use without creating an account. Advertising may appear on this page; the tool remains free to use. Use the controls above and check the result against your requirements.

What is an HMAC?

HMAC (Hash-based Message Authentication Code) proves a message is authentic and unmodified using a shared secret key. The sender computes HMAC(secret, message) and attaches the result; the receiver recomputes it with the same secret — if the two match, the message is genuine. It is used for webhook signatures, API authentication and JWT signing.

How do I generate an HMAC-SHA256 signature?

Paste your message, enter your secret key, pick SHA-256 and hit Generate. The tool computes HMAC-SHA256 with the WebCrypto API entirely in your browser and shows the signature in hex, base64 and base64url. Copy whichever encoding your API expects.

How do I verify an HMAC signature?

Generate the signature for your message and secret on this page, then paste the signature you received into the verify box. The tool compares them and shows a clear match/mismatch verdict — the fastest way to debug "signature mismatch" errors in webhook integrations.

Which algorithm should I use — SHA-1, SHA-256 or SHA-512?

Use whatever your API or webhook provider specifies — most use HMAC-SHA256 (Razorpay, Stripe and GitHub webhooks all do). SHA-1 is legacy and should be avoided for new integrations; SHA-512 is stronger but slower and produces longer signatures. When in doubt, SHA-256 is the safe default.

Hex or base64 output — which do I need?

It depends on the API. Razorpay sends webhook signatures as lowercase hex; Stripe uses hex too; many others use base64. This tool shows hex, base64 and base64url side by side, so just copy the one your documentation asks for.

Is it safe to paste my secret key here?

Yes — the signature is computed with the WebCrypto API inside your own browser; your secret and message never leave your device and are never sent to any server. Still, as a habit, prefer test-mode secrets when debugging and never paste production secrets into any website you do not fully trust.

How do I verify a Razorpay webhook signature?

Compute HMAC-SHA256 with your webhook secret as the key and the raw request body as the message, hex-encoded, then compare it with the X-Razorpay-Signature header. Critical: use the raw body bytes — do not JSON-parse and re-stringify the payload first, or the signature will never match. Click the "Razorpay webhook" preset on this page for the exact setup.

What is the Razorpay payment signature format?

For Razorpay Checkout, the signature is HMAC-SHA256 of the string razorpay_order_id + "|" + razorpay_payment_id, keyed with your key secret, hex-encoded. Compare it against the razorpay_signature returned by Checkout. The "Razorpay payment" preset on this page fills in that message template for you.

Why does my webhook signature never match?

The usual suspects, in order: (1) the message bytes differ — you hashed parsed-and-reserialized JSON instead of the raw body, or an encoding/trailing newline crept in; (2) the wrong secret (test vs live, or the API secret instead of the webhook secret); (3) the wrong algorithm or output encoding (hex vs base64). Paste the exact raw payload here and compare step by step.

HMAC vs hash — what's the difference?

A plain hash (like SHA-256) is a fingerprint anyone can compute — it proves integrity but not origin. HMAC mixes in a secret key only you and the sender know, so a matching HMAC proves both integrity AND authenticity: the message is unmodified and it came from someone holding the secret.

Can HMAC be reversed or decrypted?

No. HMAC is not encryption — there is no decryption. Like a hash, it is one-way: you cannot recover the message or the secret from the signature. The only way to "break" it is to guess the secret by brute force, which is why secrets must be long and random.

Does this HMAC calculator work offline?

The computation itself is 100% local — once the page has loaded, no network is needed to generate or verify signatures. Note that the WebCrypto API requires a secure context, so the page must be served over HTTPS (or localhost) for the calculator to work.