HMAC Generator — Free Online HMAC-SHA256 Signature Tool
Type a message and a secret key to compute its HMAC signature with HMAC-SHA-1, SHA-256, SHA-384, or SHA-512. Get the result in hex, Base64, and Base64URL. Free and 100% in your browser — keys and messages never leave your device.
Default for modern API signing (AWS Sig V4, GitHub webhooks, Stripe, JWT HS256).
Key bytes: 15 · Recommended ≥32⚠ shorter than hash output — reduces effective security
—Most standard signing protocols (AWS, GitHub, Stripe)
—PHP, Java, generic HTTP headers
—JWT signatures, OAuth — URL-safe alphabet, no padding
HMAC alone does not prevent replay attacks. For request signing, always include a timestamp and a nonce in the signed payload, and reject requests older than a short window (5-15 minutes is standard).
Four Algorithms
HMAC-SHA-1 (legacy compatibility), SHA-256 (modern default), SHA-384, and SHA-512 — covering JWT HS256/384/512, AWS Sig V4, GitHub webhooks, and TOTP.
Three Output Formats
Hex (lowercase, standard for most signing protocols), Base64 (PHP, Java APIs), Base64URL (JWT signatures, OAuth). One-click copy for each format.
Native Web Crypto
Uses crypto.subtle.importKey + sign — the browser's vetted implementation. No JavaScript SHA implementation; exact same bytes a Node.js or Python HMAC would produce.
100% Client-Side
Secret keys are highly sensitive. They never leave your browser tab. No fetch, no analytics, no logging. Works offline once loaded.
HMAC Generator: Free Keyed-Hash Signatures in Your Browser
An HMAC generator takes a message and a secret key and returns a fixed-size signature that only someone holding the key can reproduce. Pick an algorithm — HMAC-SHA-256 is the default — then read the result in hex, Base64, or Base64URL. This tool computes signatures with the browser's Web Crypto API, free, with keys and messages never leaving your device.
How to generate an HMAC signature
- Choose an algorithm: HMAC-SHA-256 for almost everything, or SHA-384/SHA-512 when a protocol like JWT HS384/HS512 requires it.
- Type or paste your message — the exact bytes you want to sign, such as a raw webhook body.
- Enter your secret key. The byte counter shows its length and warns if it is shorter than the hash output. Toggle Show to reveal the masked field.
- Read the signature in all three encodings; the output updates instantly as you type — there is no submit button.
- Press Copy on the encoding your downstream system expects: hex for AWS/GitHub/Stripe, Base64 for PHP/Java, Base64URL for JWT and OAuth.
What is HMAC and how does it work?
HMAC stands for Hash-based Message Authentication Code. It is not a hash function on its own — it wraps an existing one (SHA-256, SHA-512, etc.) so the output depends on a secret key as well as the message. A plain hash answers "has this data changed?" HMAC answers a stronger question: "did this data come from someone who knew the secret, and is it unchanged?" Only parties holding the key can produce a valid signature, which is why HMAC underpins webhook verification, API request signing, and JWT HS256 tokens.
Internally, HMAC hashes the message twice using the key XORed with two fixed pads: H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ message)). That nested construction is what makes HMAC immune to the length-extension attacks that affect a raw SHA-256 used directly as a signature. The algorithm is defined in RFC 2104 (1997) and standardized by NIST FIPS 198-1.
"The authentication key K can be of any length up to B, the block length of the hash function. Applications that use keys longer than B bytes will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."— RFC 2104, §3 (Keys)
This tool implements HMAC with crypto.subtle.importKey('raw', key, { name: 'HMAC', hash }, false, ['sign']) followed by crypto.subtle.sign('HMAC', …) — the same vetted implementation that powers HTTPS and TLS. Both message and key are UTF-8 encoded with TextEncoder, so the bytes you see match what a Node.js, Python, or Go HMAC of the same inputs would produce.
Worked examples: message + key → signature
HMAC-SHA-256 · message "Hello, Toolk!" · key "your-secret-key" · hex
b8e7...e1a4 (64 hex chars = 32 bytes = 256 bits)
Same inputs · Base64 vs Base64URL
The three outputs encode identical bytes. Base64 may contain +, /, and trailing = padding; Base64URL swaps them to - and _ and drops the = — exactly the JWT signature form.
Change one byte of the key → total change
Edit the key from your-secret-key to your-secret-keys and the entire signature changes, not just the end. This avalanche effect is why a leaked signature reveals nothing about the key.
Edge case · signing parsed JSON instead of the raw body
A common verification failure: you receive a webhook, parse the JSON, re-serialize it, then HMAC that. Re-serializing reorders keys and changes whitespace, so your signature will never match the sender's. Always HMAC the raw request body bytes exactly as received — before any JSON parsing.
Algorithm reference: output and recommended key length
Recommended key bytes below match this tool's warning threshold — it flags any key shorter than the hash output. Block size is the RFC 2104 value B at which a longer key gets pre-hashed.
| Algorithm | Output | Recommended key | Block size (B) | Typical use |
|---|---|---|---|---|
| HMAC-SHA-1 | 160-bit / 20 bytes | ≥ 20 bytes | 64 bytes | Legacy: TOTP, OAuth 1.0a |
| HMAC-SHA-256 | 256-bit / 32 bytes | ≥ 32 bytes | 64 bytes | AWS Sig V4, webhooks, JWT HS256 |
| HMAC-SHA-384 | 384-bit / 48 bytes | ≥ 48 bytes | 128 bytes | JWT HS384, TLS 1.3 suites |
| HMAC-SHA-512 | 512-bit / 64 bytes | ≥ 64 bytes | 128 bytes | JWT HS512, maximum output |
Plain hash vs HMAC — when each applies
| Aspect | Plain hash (SHA-256, MD5) | HMAC (HMAC-SHA-256, etc.) |
|---|---|---|
| Inputs | One: the message | Two: message + secret key |
| Purpose | Detect accidental corruption; one-way mapping | Detect tampering by attackers; authenticate sender |
| Security model | No secret — anyone can compute and verify | Verifier needs the secret; attackers without it cannot forge |
| Output length | Same as underlying hash (e.g. 256 bits for SHA-256) | Same as underlying hash |
| Replay protection | None inherent | None inherent — include timestamp + nonce in the signed payload |
| Length-extension | SHA-1, SHA-2 vulnerable when used as raw signature | Designed to defeat length-extension attacks (RFC 2104) |
For the full breakdown, read our guide on hashing vs encryption vs encoding.
Where HMAC is standard
| Context | How HMAC is used |
|---|---|
| JWT signing (HS256/384/512) | Secret-keyed token signing. HS256 = HMAC-SHA-256 is the default JWT signature; key MUST be at least as long as the hash output. |
| Webhook verification | GitHub, Stripe, Slack, GitLab — all sign outgoing webhooks with HMAC-SHA-256 and an X-Hub-Signature header for receivers to verify. |
| AWS Signature V4 | Every authenticated AWS request signs the canonical request with HMAC-SHA-256 chained four times through derived keys. |
| OAuth 1.0 (legacy) | OAuth 1.0a uses HMAC-SHA-1 to sign requests. Modern OAuth 2.0 dropped HMAC in favor of TLS + Bearer tokens. |
| API request signing | Custom API auth schemes (HMAC headers on requests). Always include a timestamp in the signed payload to prevent replay attacks. |
| TOTP-derived secrets | Google Authenticator and similar use HMAC-SHA-1 over time + secret. The HOTP/TOTP RFCs (4226, 6238) standardize the algorithm. |
The key-length detail most generators hide
There is a real sweet spot for an HMAC-SHA-256 key: 32 to 64 bytes. Below 32 bytes, this tool warns you because the key is shorter than the 256-bit hash output, cutting brute-force resistance. Above 64 bytes — the SHA-256 block size B — RFC 2104 silently SHA-256s your key down to 32 bytes first. So a 200-byte passphrase gives you no more security than a well-chosen 32-byte key, and a 65-byte key and its 32-byte SHA-256 hash produce the identical HMAC. Most tools never tell you this; it is why openssl rand -hex 32 is the right key recipe.
One more gotcha verifiers hit: HMAC has no built-in replay protection. A captured signed request can be re-sent verbatim and will still verify. Always sign a timestamp and a nonce alongside the body, and reject anything older than a 5-to-15-minute window. Generate those nonces with our UUID Generator.
Verifying a signature safely (constant-time)
To verify, recompute the HMAC from the same raw body, key, and algorithm, then compare it to the received signature with a constant-time check. Never use == or string equality: those short-circuit on the first mismatched byte and leak how many leading bytes were correct, letting an attacker reconstruct the signature one byte at a time over many requests. Use crypto.timingSafeEqual (Node.js), hmac.compare_digest (Python), or hash_equals (PHP). GitHub's own webhook validation docs spell out the same constant-time requirement.
1. Use SHA-256 or stronger
SHA-1 has known collision attacks (since 2017). For new code, default to HMAC-SHA-256 unless an existing protocol requires a specific algorithm.
2. Key length ≥ hash output length
A 16-byte key for HMAC-SHA-256 leaves ~128 bits of brute-force resistance — minimum for production. Use 32 bytes (= 256 bits) ideally.
3. Constant-time comparison when verifying
Naive string equality leaks timing information. Use crypto.subtle.verify or a timing-safe comparison function on the server side.
4. Include timestamp + nonce in signed payload
HMAC alone does not prevent replay — an attacker can re-send a captured request. Sign body + timestamp; reject requests older than 5 minutes.
5. Rotate keys regularly
Compromised keys forge unlimited valid signatures. Maintain key-rotation procedures and use key IDs (kid) so receivers know which key to verify with.
Runs 100% in your browser
Your keys and messages never leave your device. Signatures are computed locally with the Web Crypto API — there is no fetch, no XHR, and no analytics event carrying your input, which you can confirm in the DevTools Network tab. I tested every algorithm against known HMAC vectors and against Node.js crypto.createHmac output for the same UTF-8 message and key, including short keys (the warning fires), 64-byte keys, and keys longer than the block size — the hex, Base64, and Base64URL results matched byte for byte. No uploads, nothing leaves your device.
Frequently asked questions
Is this HMAC generator free?
Yes — 100% free with no signup and no usage cap. All four algorithms and all three output formats are available.
Which HMAC algorithm should I use?
Use HMAC-SHA-256 by default — it is what AWS Sig V4, GitHub and Stripe webhooks, and JWT HS256 use. Pick SHA-384 or SHA-512 only when a protocol requires it, and avoid SHA-1 in new code.
How is HMAC different from a plain hash?
A plain hash takes only the message, so anyone can compute and verify it. HMAC also takes a secret key, so only key holders can produce a valid signature — that is what authenticates the sender.
Is my data sent to any server?
No. Every signature is computed locally with the browser's Web Crypto API. Open DevTools, watch the Network tab, and compute a signature — zero requests fire.
Related encoding, security & crypto tools
One-way MD5/SHA digests without a key
JWT DecoderInspect HS256/384/512 token signatures
Base64 EncoderEncode text and bytes to Base64
Base64 DecoderDecode Base64 and Base64URL strings
URL EncoderPercent-encode values for signed query strings
URL ParserSplit a URL into parts before signing
Image to Base64Convert an image to a Base64 data URI
Base64 to ImageRender a Base64 string back to an image
JSON FormatterPretty-print a payload before you sign it
Guide: JWT Structure ExplainedHow HS256 uses HMAC to sign tokens
Guide: Hashing vs Encryption vs EncodingWhere HMAC fits among the three
All ToolsBrowse the full Toolk developer toolkit
Last updated: June 2, 2026 · Runs 100% in your browser — no uploads, nothing leaves your device.
Need a different tool?
Browse all 89 free, in-browser tools — or tell us what we should build next.