HMAC Generator Online Free | Generate HMAC Signatures with Any Key

🔒 Security Free Forever

HMAC Generator

Generate HMAC signatures using SHA-256, SHA-512, SHA-384, or SHA-1. Paste your message and secret key, pick an algorithm, and get the hex or Base64 output instantly. Runs entirely in your browser.

All Security Tools
🔒 Everything runs in your browser. Your message and secret key are never sent to any server. Use this freely with real keys — nothing leaves your device.

Algorithm

Key encoding:

Verify a signature

About This Tool

How this HMAC generator signs messages using the browser’s own crypto engine

HMAC, keyed hash message authentication code, proves two things at once: that a message has not been altered and that whoever produced it knew the secret key. This tool computes real HMAC signatures using the Web Crypto API’s crypto.subtle interface, the same cryptographic engine built into the browser that TLS and WebAuthn rely on. It does not implement its own hash routines in JavaScript, which matters, because a hand-rolled HMAC is exactly the kind of thing that quietly gets the byte handling wrong under edge cases. Everything runs locally. Your key and message never leave the page.

What actually happens on Generate

Step 1 Decode the key into bytes Your secret key can be entered as UTF-8 text, hex, or Base64. Each encoding has its own decoder, hex through manual byte-pair parsing with validation for odd-length or non-hex input, Base64 through atob with automatic base64url normalisation.
Step 2 Import the key crypto.subtle.importKey wraps the raw key bytes into a non-extractable CryptoKey object scoped specifically to HMAC with your chosen hash algorithm, restricted to the sign operation only.
Step 3 Sign the message The message is UTF-8 encoded with TextEncoder, then passed to crypto.subtle.sign('HMAC', cryptoKey, msgBytes), which returns the raw signature as an ArrayBuffer.
Step 4 Encode the output three ways The same signature buffer is rendered as lowercase hex, standard Base64, and URL-safe Base64 without padding, all three computed and cached so switching the output tab is instant with no re-signing.
// the actual signing call, from the tool source var cryptoKey = await window.crypto.subtle.importKey( ‘raw’, keyBytes, { name: ‘HMAC’, hash: { name: hmAlgo } }, false, [‘sign’] ); var msgBytes = new TextEncoder().encode(message); var sigBuf = await window.crypto.subtle.sign(‘HMAC’, cryptoKey, msgBytes);

The hash function itself, SHA-256 by default with other SHA-2 family options selectable, is not implemented by this tool at all. That work happens inside the browser’s native crypto implementation, which is audited, hardware accelerated where available, and constant time in ways a JavaScript loop cannot reliably guarantee. This is the correct way to do HMAC in a browser: never write your own SHA-256.

Verifying a signature you already have

Paste a candidate signature into the verify field and the tool autodetects whether it looks like hex or Base64, normalises it to lowercase hex, and compares it against the signature it just generated for the current message and key. A match confirms the message, key and algorithm all line up. The comparison itself is a plain string equality check in single threaded JavaScript, not a constant time comparison, which is a reasonable tradeoff for a browser tool checking your own values but not something you should model production verification code after.

Output formatCharacter setTypical use
Hex0 to 9, a to f, lowercaseDebugging, API signature headers, log-friendly
Base64Standard alphabet with paddingCompact transport in JSON bodies
Base64URLURL-safe alphabet, no paddingQuery strings, JWT signature segments
Key encoding changes the signature entirely. Typing the literal text mysecret as UTF-8 produces a completely different signature than entering those same eight characters interpreted as hex, since hex decoding treats every two characters as one byte. If a signature you are trying to reproduce does not match, check the key encoding dropdown before assuming the key itself is wrong. This trips up more people than any other part of HMAC verification.

Two things worth knowing about scope

Key is never marked extractable

The importKey call sets the extractable flag to false, meaning the CryptoKey object cannot be exported back out once created within that call, a minor defensive habit that mirrors how you would build key handling in a real signing service.

All formats table computed once

The Show All Formats panel does not re-sign anything, it just reads the three already-cached encodings of the same signature buffer, so toggling it costs nothing extra in computation.

RFC 2104, HMAC definition Web Crypto API, crypto.subtle SHA-2 family hashing Client-side only, no network call
  • RFC 2104 is the original HMAC specification, defining the inner and outer padding construction around a hash function.
  • FIPS 198-1 is NIST’s formal standard for the keyed-hash message authentication code.
  • W3C Web Cryptography API specifies the SubtleCrypto interface this tool calls directly, including the HMAC sign and importKey operations.
  • JWT introduction is useful context since HS256 tokens, the most common JWT signing scheme, are exactly an HMAC-SHA256 signature over a Base64URL encoded header and payload.

Where HMAC is used

Verifying a webhook payload from Stripe, GitHub or similar services that sign requests with a shared secret, debugging why a JWT HS256 signature does not validate, hand checking an API request signature before it ships in production code, and teaching or learning how HMAC actually differs from a plain hash, since a plain SHA-256 of a message plus key is not the same construction and is vulnerable to length extension attacks that HMAC’s nested padding specifically avoids.

Common Questions

Questions About HMAC generator

A regular hash (SHA-256, MD5, etc.) takes a message and produces a fingerprint. Anyone can compute the same hash for the same message. HMAC adds a secret key to that process, so only people who know the key can produce or verify the signature. This makes HMAC suitable for authentication, while plain hashing is only suitable for integrity checking.

The provider (e.g. Stripe, GitHub) computes HMAC-SHA-256 of the raw request body using a shared secret key and sends the result in a header. Your server does the same computation with the same key and compares. If they match, the request is genuine and unmodified. Use this tool to replicate that computation manually when debugging or testing webhooks.

Yes. This tool runs entirely in your browser using the Web Crypto API. Nothing is sent to a server. You can verify this by opening your browser’s network tab before using the tool — no outbound requests are made when you generate. That said, never use production secrets on any third-party website you cannot verify. The fact that this tool is client-side makes it safer than most, but your best option for high-stakes keys is always a local script or your server’s own HMAC library.

It depends on what the receiving system expects. Most API docs specify this explicitly. Stripe uses hex. GitHub webhook signatures use hex with a “sha256=” prefix. JWT uses Base64URL (no padding, URL-safe characters). If you are building something yourself, Base64 is more compact — 44 characters for SHA-256 vs 64 for hex. Base64URL is best for headers and URLs since it avoids special characters.

RFC 2104 recommends keys at least as long as the hash output. For HMAC-SHA-256 that means at least 32 bytes (256 bits). Keys longer than the block size (64 bytes for SHA-256) are hashed first, so there is no benefit beyond 64 bytes. In practice, generate a random 32-64 byte key using a cryptographically secure random number generator and store it securely as an environment variable, not in source code.

SHA-1 is broken for collision resistance — an attacker can craft two different messages with the same hash. But HMAC’s security does not rely on collision resistance; it relies on the hash being a pseudo-random function. HMAC-SHA-1 remains computationally secure against forgery attacks as long as the key is secret. It is still used in OAuth 1.0 and some legacy systems. Avoid it for new work, but it is safe to include for compatibility testing.

Privacy Overview

Cookies let this site remember your preferences and show us which tools people actually use. Full detail sits in our Privacy Policy.