Free Tool · Client-Side Only

HMAC Generator
& Verifier.

Generate and verify HMAC-SHA256/384/512 signatures. Perfect for debugging webhook signatures, API request signing, and data integrity checks.

✍️

Generate HMAC

⚠️ Key is fewer than 16 characters — use a longer, random key for production.
—
✅

Verify Signature

Uses the same message and key from the generator above. Paste the expected signature to compare.

✅ Signatures match — integrity verified
❌ Signatures do NOT match — payload may have been tampered with
📖

Common Use Cases

🐙 GitHub Webhook Verification
// Header: X-Hub-Signature-256: sha256=<hex> // Algorithm: HMAC-SHA256, key = your webhook secret // Message: raw request body (bytes, not parsed JSON) const sig = 'sha256=' + hmacSHA256(body, secret) if (!timingSafeEqual(sig, req.headers['x-hub-signature-256'])) throw new Error('Invalid')
💳 Stripe Webhook Verification
// Header: Stripe-Signature: t=<ts>,v1=<hex> // Signed payload: timestamp + '.' + rawBody // Algorithm: HMAC-SHA256, key = endpoint signing secret const payload = timestamp + '.' + rawBody const expected = hmacSHA256(payload, stripeSecret)
🔑 API Request Signing
// Common pattern: sign method + path + timestamp + body hash const canonicalReq = method + '\n' + path + '\n' + timestamp + '\n' + sha256(body) const signature = hmacSHA256(canonicalReq, apiSecret) // Send in header: Authorization: HMAC-SHA256 sig=<hex>,ts=<timestamp>

Frequently asked

What is an HMAC actually used for?
Proving that a message came from someone who holds a shared secret and was not altered in transit. The three everyday cases are webhook signatures (GitHub's X-Hub-Signature-256, Stripe's Stripe-Signature, Slack's X-Slack-Signature), signed API requests (AWS SigV4 is an HMAC chain), and tamper-evident tokens such as HS256 JWTs and signed cookies.
How is HMAC-SHA256 different from a plain SHA-256 hash?
A plain hash has no secret: anyone can recompute it, so it only detects accidental corruption. HMAC mixes a secret key into the hash in a specific two-pass construction, so producing a valid tag requires the key. It also avoids the length-extension weakness of naively hashing secret + message.
Is my secret key sent anywhere when I use this tool?
No. Signatures are computed with the browser's built-in crypto.subtle API and nothing is transmitted. You can confirm this in DevTools → Network: no requests are made when you click Generate or Verify.
How do I verify a GitHub webhook signature correctly?
Compute HMAC-SHA256 over the raw request body (not the parsed JSON) with your webhook secret, hex-encode it, prefix with sha256=, and compare to the X-Hub-Signature-256 header using a constant-time comparison such as hmac.compare_digest in Python or crypto.timingSafeEqual in Node. A plain == leaks timing information.

Related free tools

Read next

Cryptographic implementation vulnerabilities

The ways correct algorithms get used incorrectly — timing-unsafe compares, key reuse, truncated MACs — and how to spot them in code review.

Signing is easy. Verifying everywhere is not.

Find webhook handlers that
never check the signature.

AquilaX SAST traces every inbound webhook and API handler in your codebase and flags the ones that skip HMAC verification, compare signatures with ==, or fall back to a hard-coded secret.

Free plan is permanent · unlimited scans · GitHub, GitLab, Bitbucket & Azure DevOps