XConvert
Downloads
Pricing

Generate HMAC Online

Generate an HMAC for your input data directly in your browser and download the result instantly.

Message & key
Options
HMAC
HMAC will appear here once you enter a message and secret.

How to Generate an HMAC Online

  1. Enter Your Message: Paste or type the payload you want to authenticate — request body, webhook event, session token, or any UTF-8 text. The message stays in your browser; nothing is uploaded.
  2. Enter the Secret Key: Paste the shared secret used by both signer and verifier. For best security, use a random key at least as long as the hash output (32 bytes for SHA-256, 64 bytes for SHA-512). You can generate one with our Password Generator or a UUID as a 16-byte seed.
  3. Pick a Hash Algorithm: Choose HMAC-SHA-256 (recommended default), HMAC-SHA-384, or HMAC-SHA-512 for stronger security. HMAC-SHA-1 is still listed for compatibility with legacy systems (AWS SigV2, older OAuth) but should not be used for new designs.
  4. Pick Output Encoding and Generate: Choose Hex (lowercase hex string — the most common transport format) or Base64 (shorter, used by AWS SigV4 and many webhook providers). Click Generate and use Copy to grab the MAC. All hashing runs locally via the Web Crypto API.

Why Generate an HMAC?

HMAC (Hash-based Message Authentication Code) lets two parties who share a secret key prove that a message wasn't tampered with and that it came from someone who knows the key. It's defined in RFC 2104 and is the backbone of most modern API authentication. Unlike a plain hash(secret + message), HMAC uses a nested construction H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ M)) that is provably resistant to length-extension attacks on Merkle–Damgård hashes like SHA-1, SHA-256, and SHA-512.

  • API request signing — AWS SigV4 — AWS Signature Version 4 derives a per-request signing key with four chained HMAC-SHA256 operations (date, region, service, "aws4_request"), then HMAC-SHA256s the canonical request. Documented under "AWS4-HMAC-SHA256" in the S3/IAM API reference.
  • Webhook signature verification — Stripe, GitHub, Shopify — Stripe signs {timestamp}.{raw_body} with HMAC-SHA256 using your endpoint secret and ships the result as v1=... in the Stripe-Signature header. GitHub uses X-Hub-Signature-256: sha256=.... Always compute the HMAC against the raw request body — re-serialised JSON will not match.
  • JWT HS256 / HS384 / HS512 signing — Symmetric JWTs use HMAC over base64url(header).base64url(payload). Inspect the result with our JWT Decoder.
  • Session token and cookie integrity — Frameworks like Rails (signed cookies), Express cookie-session, and Django signing attach an HMAC tag so the server can verify a cookie hasn't been edited client-side without a database lookup.
  • CSRF tokens (double-submit pattern) — Encode HMAC(session_id, server_secret) as the CSRF token; the server can validate without storing per-session state.
  • Database row signing and audit logs — Append an HMAC over each log line or row so tampering is detectable, even by an attacker with write access (provided the key is held elsewhere).

Need a plain digest instead of a keyed MAC? Use our Hash Generator for SHA-256, SHA-512, MD5, and other one-shot hashes.

HMAC Algorithm Comparison

Algorithm Output size Block size Security strength* Recommended use
HMAC-SHA-1 160 bits (20 bytes) 64 bytes ~128 bits for HMAC use Legacy compatibility only (AWS SigV2, older TOTP, OAuth 1.0a) — no known practical break against HMAC-SHA-1, but NIST recommends SHA-2/3 for new code per SP 800-107
HMAC-SHA-256 256 bits (32 bytes) 64 bytes 256 bits Default for new designs — AWS SigV4, Stripe, GitHub, Shopify, JWT HS256
HMAC-SHA-384 384 bits (48 bytes) 128 bytes 384 bits Higher-assurance APIs; immune to length-extension even in raw form
HMAC-SHA-512 512 bits (64 bytes) 128 bytes 512 bits High-security signing, large keys, JWT HS512 — faster than SHA-256 on 64-bit CPUs

*Per NIST SP 800-107 Rev. 1, the effective HMAC strength is min(strength_of_key, 2 × L) where L is the output length; truncating output below ~96 bits is discouraged for general use.

Common HMAC Use Cases and Concrete Examples

Use case Algorithm Where the MAC lives Notes
AWS S3 / IAM request signing HMAC-SHA-256 Authorization: AWS4-HMAC-SHA256 ... header Four-step key derivation per request
Stripe webhook events HMAC-SHA-256 Stripe-Signature: t=...,v1=... header Signs timestamp.body
GitHub webhook events HMAC-SHA-256 X-Hub-Signature-256: sha256=... header Signs the raw request body
Shopify webhooks HMAC-SHA-256 (Base64) X-Shopify-Hmac-Sha256 header Base64-encoded, not hex
JWT (HS256/HS384/HS512) HMAC-SHA-256/384/512 Third dot-separated segment Base64url; signs header.payload
TOTP / Google Authenticator HMAC-SHA-1 (per RFC 6238) 6-digit code derivation SHA-1 still standard for TOTP interop

Frequently Asked Questions

Why HMAC instead of just hashing the secret with the message?

Concatenations like SHA-256(secret ‖ message) or MD5(secret ‖ message) are vulnerable to length-extension attacks because MD5, SHA-1, and the SHA-2 family (except SHA-384 and SHA-512/256) use the Merkle–Damgård construction. An attacker who has a valid hash(secret ‖ message) and knows the length of the secret can compute hash(secret ‖ message ‖ padding ‖ attacker_data) without ever learning the secret — they just resume the hash's internal state. HMAC's nested H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ M)) construction breaks that property because the outer hash takes a fixed-length input (the inner hash's digest), so there's no internal state for an attacker to extend. This is why every modern API signing scheme uses HMAC and not raw H(secret ‖ message).

Is HMAC-SHA-1 still safe in 2026?

For HMAC purposes specifically, yes — but only for existing systems. The 2017 SHAttered collision and 2020 chosen-prefix collision attacks against raw SHA-1 do not transfer to HMAC-SHA-1 because HMAC's security relies on the hash's PRF properties rather than collision resistance. There is no published practical attack on HMAC-SHA-1. However, NIST SP 800-107 Rev. 1 and the broader NIST deprecation timeline for SHA-1 (effective end of 2030 per NIST's December 2022 announcement) mean new designs should use HMAC-SHA-256 or stronger. TOTP and legacy AWS SigV2 are exceptions where SHA-1 remains the documented standard for interop reasons.

What key length should I use?

Per RFC 2104 §3, the key can be any length, but two thresholds matter. Keys shorter than the hash output (32 bytes for SHA-256, 64 for SHA-512) reduce the effective security strength to the key's entropy — a 16-byte SHA-256 key gives you 128-bit HMAC strength, not 256-bit. Keys longer than the hash block size (64 bytes for SHA-256, 128 bytes for SHA-512) get pre-hashed before use, which is fine but offers no additional security beyond the hash output size. The practical recommendation: generate a random key exactly equal to the hash output size — 32 bytes for SHA-256, 48 for SHA-384, 64 for SHA-512.

How do I verify an HMAC in constant time?

Always use a constant-time comparison — never ===, ==, strcmp, or Buffer.compare. A naive byte-by-byte loop returns early on the first mismatch, leaking via timing how many leading bytes were correct; an attacker on the same network can iteratively guess each byte. Use the language's documented primitive: Node.js crypto.timingSafeEqual(a, b) (both must be equal-length Buffers), Python hmac.compare_digest(a, b), Go hmac.Equal(macA, macB), Ruby OpenSSL.fixed_length_secure_compare, PHP hash_equals($known, $user). Browser code can use subtle.timingSafeEqual where supported, or implement the loop with XOR-OR accumulation manually.

Why is my HMAC different from the server's even though my message and key look identical?

Almost always one of: (1) trailing newline or whitespace in the message (Stripe and GitHub sign the raw request body byte-for-byte — re-parsed JSON will not round-trip identically because of key order, whitespace, and Unicode escaping); (2) hex vs Base64 encoding mismatch on the output; (3) key passed as a hex string instead of decoded bytes (a 64-character hex string is 64 bytes when used as text, 32 bytes when decoded); (4) UTF-8 vs UTF-16 encoding of the message in environments that default to UTF-16 (older .NET); (5) line endings flipped from \n to \r\n by Git or an editor. Diff the input bytes — not the rendered strings — to find the discrepancy.

How should I rotate webhook signing secrets without downtime?

Use a "multi-key acceptance" window. (1) Generate a new secret and start signing outbound webhooks with it. (2) On the receiver, accept either the old or the new HMAC during a transition window (24–72 hours is typical). Stripe, GitHub, and Shopify all support this — Stripe lets you have two active endpoint secrets per endpoint for exactly this purpose. (3) After the window, retire the old secret. Never rotate by hard-cutting on a deploy — in-flight retries signed with the old secret will fail verification.

HMAC versus an RSA or ECDSA signature — which should I use?

HMAC is symmetric: signer and verifier share the same secret, so anyone who can verify can also forge. RSA/ECDSA signatures are asymmetric: the signer holds a private key, verifiers hold the public key, and verifiers cannot forge. Pick HMAC when you control both ends of the channel (your server signs, your webhook receiver verifies — same trust boundary), when you want simplicity and speed (HMAC-SHA-256 is roughly 10–100× faster than RSA-2048 and produces a 32-byte tag vs RSA's 256 bytes), and when key distribution is solved (you can deliver the secret over a secure channel once). Pick RSA/ECDSA when third parties need to verify but should not be able to issue tokens (public JWTs signed RS256/ES256), when you need non-repudiation in a legal/audit sense, or when distributing a shared secret to many verifiers is unacceptable. JWT supports both — HS256 is HMAC; RS256 and ES256 are RSA and ECDSA.

Are my message and key sent to your servers?

No. The generator uses the browser's Web Crypto API (crypto.subtle.sign('HMAC', key, data)) to compute the MAC entirely in your tab. Nothing is uploaded, logged, or persisted — you can verify by opening DevTools → Network and confirming zero outbound requests when you click Generate. Safe to paste production webhook secrets and signing keys during debugging.

Related Generate tools
Nanoid GeneratorUlid GeneratorKsuid GeneratorFake Name GeneratorFake Email GeneratorFake Address GeneratorFake Phone GeneratorRandom Ip

Image Tools

Image CompressorCompress JPEGCompress PNGCompress GIFCompress WebPImage ConverterJPG ConverterImage Resizer

Video Tools

Video CompressorCompress MP4MP4 to GIFVideo to GIFVideo ConverterMP4 ConverterVideo Cutter

Audio Tools

Audio CompressorCompress MP3Compress WAVAudio ConverterMP3 ConverterFLAC to MP3Audio Cutter

Document Tools

Compress PDFMerge Images to PDFSplit PDFPDF to JPGUnzip FilesRAR Extractor
© 2026 XConvert.com. All Rights Reserved.
About UsPrivacy PolicyTerms of ServiceContactHelp Us Grow