HMAC Generator

Keyed-hash message authentication codes — SHA-256, SHA-384, SHA-512.

Free HMAC generator for SHA-256, SHA-384 and SHA-512. Enter a secret key and message to produce a keyed hash for API signatures and webhook verification — runs entirely in your browser. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is HMAC used for?

HMAC binds a message to a shared secret key so the receiver can verify both integrity and authenticity. It is widely used to sign API requests, verify webhook payloads (Stripe, GitHub, Slack) and protect tokens.

HMAC generator — SHA-256, SHA-384 and SHA-512

A HMAC (Hash-based Message Authentication Code, RFC 2104) combines a secret key with your message to produce a keyed hash. Anyone who knows the key can recompute the same value, which proves the message was not tampered with and came from someone holding the key. It is the standard way to sign API requests and verify webhook payloads.

How it works

The tool uses the browser’s Web Crypto API. It UTF-8 encodes your secret key and imports it as an HMAC key bound to the chosen hash (SHA-256, SHA-384 or SHA-512), UTF-8 encodes your message, then calls crypto.subtle.sign to produce the authentication code. The resulting bytes are rendered as a lowercase hex string. Internally HMAC hashes the key combined with the message twice with inner and outer padding, which is what makes it resistant to length-extension attacks that affect a naive key-plus-message hash. The output updates live as you type.

Example

With key topsecret and message hello, HMAC-SHA-256 produces a fixed 64-character hex string. Re-running with the same inputs always gives the same value; changing a single character of either input changes the entire output.

AlgorithmOutput bitsHex length
HMAC-SHA-25625664
HMAC-SHA-38438496
HMAC-SHA-512512128

Everything runs locally in your browser via the Web Crypto API — your key and payload are never sent over the network.

Step-by-step: verifying a Stripe webhook

Webhook signature verification is one of the most common real-world uses for HMAC. Here is how the process works for Stripe as a concrete example:

  1. Stripe sends a POST request to your endpoint with a Stripe-Signature header that looks like t=1234567890,v1=abc123....
  2. The t= value is the timestamp Stripe signed. The v1= value is the HMAC-SHA-256 of the string timestamp + "." + raw_body, signed with your webhook endpoint’s signing secret.
  3. To verify: take the signing secret from your Stripe dashboard as the key, construct the signed payload as timestamp + "." + rawBody, compute HMAC-SHA-256, and compare to the v1= value in the header.

This tool is helpful for testing that verification manually: paste the signing secret as the key and the constructed payload string as the message, then compare the hex output to what Stripe sent. If they match, the payload is authentic.

GitHub, Slack, and most other platforms follow the same pattern with minor variations in how they format the signature header.

Why HMAC is better than a plain hash for this job

A plain SHA-256 of the message alone would let an attacker compute any signature themselves (without the key), rendering it useless for authentication. HMAC addresses this by mixing the key into the hash in a structured way.

Beyond that, HMAC is specifically resistant to length-extension attacks — a class of attack that affects SHA-256 when used naively as SHA256(key || message). The inner-and-outer padding structure of HMAC prevents an attacker from appending data to a signed message and computing a new valid signature without knowing the key.

Encoding tips: getting the inputs right

HMAC is deterministic, which means the inputs must match exactly. Two common sources of mismatch:

  • Trailing newlines — many terminals and editors add a \n at the end of copied text. If your computed HMAC does not match, check whether either input has an extra newline.
  • Hex vs. raw bytes for the key — some platforms (for example some JWT libraries) provide the secret as a base64 or hex string that must be decoded to raw bytes before use. This tool treats both key and message as UTF-8 text; if your secret is base64-encoded, decode it first.