tuliq
Runs in your browser

HMAC Signature Calculator

Computes an HMAC (Hash-based Message Authentication Code) signature for a message using a secret key — the standard way APIs and webhook providers verify a payload's authenticity. Unlike a plain hash, HMAC is keyed, so only someone holding the same secret can produce a matching signature. Uses the browser's native Web Crypto API — the same audited cryptographic code your browser already uses for TLS. Paste a message and secret, pick SHA-256/384/512, and see the signature in hex and base64 live. Paste an expected signature to check it matches, with known provider prefixes like "sha256=" stripped automatically. Runs entirely client-side — nothing is uploaded.

Enter a secret key to compute the signature.

About this tool

Computes an HMAC (Hash-based Message Authentication Code) signature for a message using a secret key — the standard way APIs and webhook providers (GitHub, Stripe, and most others) let you verify that a payload genuinely came from them and wasn't tampered with in transit. Unlike a plain hash, HMAC is keyed: only someone holding the same secret can produce a matching signature, which is what makes it useful for authentication rather than just integrity-checking. This tool uses the browser's native Web Crypto API (crypto.subtle) rather than a JavaScript HMAC implementation — the same trusted, audited cryptographic code your browser already uses for TLS. Paste a message and secret, pick SHA-256, SHA-384, or SHA-512, and the signature updates live in both hex and base64. If you're verifying an incoming webhook, paste the signature you received into the "Compare against" field — known provider prefixes like "sha256=" are stripped automatically before comparing.

What you can do

  • HMAC-SHA256, SHA384, and SHA512 — computed with the browser's native Web Crypto API
  • Paste an expected signature to check it matches, with known provider prefixes (e.g. "sha256=") stripped automatically
  • Both hex and base64 output, since different APIs expect different encodings
  • Your secret and message never leave your browser — nothing is sent anywhere

How to use

Step 1

Paste the message

The exact payload to sign — usually a webhook's raw request body.

Step 2

Enter the secret and pick an algorithm

The signature updates instantly as you type.

Step 3

Compare, if you're verifying

Paste the signature you received to see whether it matches.

Example

A GitHub-style webhook signature header looks like this:

X-Hub-Signature-256

sha256=f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

Paste the full header value (prefix included) into "Compare against" — the "sha256=" part is recognized and stripped automatically before comparing.

How your data is handled

This tool is labeled 🟢 Runs in your browser: your message and secret key are processed entirely locally using the browser's built-in Web Crypto API — nothing is uploaded to a server, logged, or retained once you leave the page. Because the secret never leaves your browser, this is safe to use even with a real production webhook secret, though as with any tool, only paste a secret you control into a page you trust.

Frequently asked questions

What's the difference between this and the Hash Generator?+

The Hash Generator computes an unkeyed hash (MD5/SHA-1/SHA-256/SHA-512) of data alone — anyone can compute the same hash from the same data. HMAC additionally takes a secret key, so only someone who knows the secret can produce a matching signature. That's what makes HMAC suitable for verifying a message's source, not just its integrity.

Why does the signature disappear when I clear the secret?+

The Web Crypto API doesn't allow a zero-length HMAC key, so a signature can't be computed without one — this isn't a bug, it's a deliberate restriction in the underlying browser API.

Is my secret key sent anywhere?+

No — the signature is computed entirely in your browser using the Web Crypto API. Nothing about your message or secret is uploaded or logged.

Why do I need to strip the "sha256=" prefix manually elsewhere but not here?+

You don't need to here — pasting the full header value (prefix included) into "Compare against" works directly, since known provider prefixes are recognized and stripped automatically before comparing.

Does this verify a JWT's signature?+

No — for that, use the JWT Decoder (which deliberately doesn't verify signatures either, for the same reason: it needs the issuer's key, which it never asks for) or the JWT Generator, which signs a token with HS256/384/512 using this same HMAC approach.

Related tools