HMAC Generator

Compute an HMAC-SHA1, HMAC-SHA256, HMAC-SHA384 or HMAC-SHA512 value from a message and secret key — for API request signing, webhook verification, and JWT (HS256) signatures. Get the output as Hex, Base64, or Base64URL.

Runs 100% in your browser — your message and secret key are never sent to a server.
The output stays empty if the message or secret key is blank.

What Is HMAC, and What Is It Used For?

HMAC (Hash-based Message Authentication Code) is a mechanism used to verify both a message's integrity and its sender. Unlike a plain hash function, HMAC also takes a secret key alongside the message and combines the two using a specific double-hashing scheme defined in RFC 2104 (key+inner padding+message is hashed first, then key+outer padding+that result is hashed again). This means only parties who know the same secret key can produce or verify a valid HMAC.

Critical distinction: HMAC is NOT the same as simply computing hash(key + message). That naive approach is vulnerable to what's called a "length-extension attack" — an attacker can append extra data on top of an existing hash and produce a new, seemingly valid hash without knowing the original message or key. HMAC's double-hash construction from RFC 2104 makes this attack mathematically impossible; that's why you should always use purpose-built HMAC for a signing mechanism, and never invent your own "key+message" concatenation.

The most common uses include API request signing (many cloud providers require an HMAC signature to prove a request wasn't tampered with), webhook verification (services like Stripe and GitHub attach an HMAC-SHA256 signature to every webhook request they send; the receiving server recomputes the same signature with its own secret key and compares it to confirm the request really came from that service), and JWT's (JSON Web Token) HS256 signing algorithm. As a developer testing a webhook integration or investigating why an API request's signature isn't validating, you can use this tool to manually reproduce and compare the expected HMAC value.

This tool runs entirely in your browser; the computation is done with the browser's built-in Web Crypto API (crypto.subtle) — neither your message nor your secret key is ever sent to a server at any stage. SHA-256 is recommended for most modern uses; as for output format, Hex offers readability, Base64 is more compact, and Base64URL can be used safely inside a URL or filename (e.g. JWT signatures).

Try This Next

Finished here? These might be your next step.

Frequently Asked Questions

HMAC (Hash-based Message Authentication Code) is a value produced by hashing a message together with a secret key, providing both integrity and authentication (RFC 2104). Only a party that knows the same secret key can reproduce and verify the same HMAC value.

A plain hash only checks data integrity — who produced it doesn't matter, anyone can compute the same hash. HMAC additionally requires a secret key, so only parties who know the key can produce a valid HMAC — giving you both integrity and authentication. Simply concatenating the key and message and hashing them (hash(key+message)) is not a substitute for HMAC — that naive approach is vulnerable to a "length-extension attack".

For most modern uses (webhook validation, API signing, JWT HS256), SHA-256 is sufficient and the common standard. Systems wanting a higher security margin may prefer SHA-384/SHA-512. SHA-1 is still supported for compatibility with some legacy systems but shouldn't be chosen for a new integration.

No. All computation in this tool is done on your device using the browser's built-in Web Crypto API (crypto.subtle); neither the message nor the secret key is ever sent to OpenMoon's servers or anywhere else.

Both represent the same bytes in a different format and are cryptographically equivalent. Hex is easier to read/log but twice as long; Base64 is more compact and common in HTTP headers/JSON. Base64URL replaces +// with -/_ and drops padding (=) so it can be used safely inside a URL or filename — JWT signatures use this form.

Last updated: