๐Ÿ—๏ธ HMAC Generator (SHA-256 / SHA-1 / SHA-512)

Last updated: March 23, 2026

๐Ÿ—๏ธ HMAC Generator

SHA-256 • SHA-1 • SHA-512  |  Hex • Base64  |  Runs locally, nothing leaves your browser

HMAC Signature SHA-256 ยท HEX
Click signature to copy

How it works: Uses the browser's built-in Web Crypto API (SubtleCrypto) to derive a keyed hash. Your message and key are never sent anywhere. SHA-256 is recommended for new integrations (AWS Signature V4, Stripe, GitHub webhooks all use it).

HMAC Explained: What It Is, Why It Matters, and How to Use It Right

Every time you receive a webhook from Stripe, push a commit to GitHub, or make a signed request to AWS, an HMAC signature is silently doing the heavy lifting. It is one of the most widely deployed authentication mechanisms on the modern internet โ€” and yet most developers only think about it when something breaks. This guide walks you through exactly how HMAC works, which algorithm to pick, common integration mistakes, and a practical checklist for every new implementation.

What HMAC Actually Does (and What It Does Not)

HMAC stands for Hash-based Message Authentication Code. It answers one specific question: Did this message come from someone who holds the shared secret key? It is not encryption โ€” the message content is not hidden. It is not a digital signature with public/private keys. It is a keyed fingerprint: run the same message through the same key with the same algorithm, and you always get the same output. Change even one byte of the message, and the output changes completely.

The construction is defined in RFC 2104 and looks like this at a high level:

HMAC(K, m) = H((K โŠ• opad) โˆฅ H((K โŠ• ipad) โˆฅ m))

Where H is the underlying hash function, K is the key, m is the message, opad and ipad are constant padding bytes. The double-hash construction prevents the length-extension attacks that plagued earlier MAC designs. You do not need to implement this yourself โ€” every language standard library includes it โ€” but understanding the shape helps when debugging why two independently computed HMACs do not match.

SHA-256 vs SHA-1 vs SHA-512: Which Algorithm to Pick

This is the question every checklist needs to answer directly:

  • SHA-256 โ€” use this for everything new. It produces a 256-bit (32-byte) output, renders as 64 hex characters or 44 Base64 characters. AWS Signature Version 4, Stripe webhooks, Shopify, GitHub, Slack, and virtually every modern API uses HMAC-SHA-256. It is fast, widely supported, and has no known practical attacks when used as an HMAC.
  • SHA-1 โ€” legacy only. SHA-1 as a standalone hash is broken for collision resistance, but HMAC-SHA-1 is still considered computationally secure when the key is kept secret. The real reason to avoid it: every new spec is moving away from it, and choosing it now means a migration later. Use it only when an existing integration forces your hand.
  • SHA-512 โ€” high-security contexts. Produces a 512-bit (64-byte) output. Roughly 2x the output size, slightly slower on 32-bit systems but actually faster than SHA-256 on 64-bit hardware due to wider internal word size. Use it when the receiving system requires it, or when you need extra margin for long-lived keys that may not be rotated frequently.

Output Format: Hex vs Base64

Both formats represent the same underlying bytes โ€” the choice is purely about what the receiving system expects.

  • Hex encodes each byte as two lowercase hex digits (0โ€“9, aโ€“f). A SHA-256 HMAC in hex is always exactly 64 characters. It is human-readable and easy to compare visually. AWS, GitHub webhooks (sha256=abc123โ€ฆ), and most command-line tools use hex.
  • Base64 encodes every 3 bytes as 4 ASCII characters, producing a more compact representation. A SHA-256 HMAC in Base64 is 44 characters (including one padding =). Stripe, JWT implementations, and many mobile API frameworks prefer Base64. The URL-safe variant replaces + with - and / with _ โ€” check whether the target system expects standard or URL-safe Base64.

The Most Common HMAC Mistakes (and How to Avoid Them)

Most HMAC bugs are not algorithm bugs โ€” they are encoding and string-handling bugs that only surface in edge cases.

  • Character encoding mismatch. Your message must be encoded to bytes before hashing. If you sign a UTF-8 string on one side and the receiver decodes it as Latin-1, the HMACs will not match for any character outside ASCII. Always explicitly encode to UTF-8 on both ends.
  • Trailing newlines. Many command-line tools add a newline when you echo a string. echo "hello" signs "hello\n", not "hello". Use printf '%s' "hello" or explicitly strip trailing whitespace before comparing.
  • Key encoding. Some APIs provide hex-encoded or Base64-encoded keys that must be decoded to raw bytes before use. If you pass a hex string as the raw key bytes, you are signing with a 64-byte key that is the ASCII encoding of hex digits โ€” not the 32-byte key the server is using.
  • Case sensitivity in hex output. Some systems expect lowercase hex (a1b2c3), others uppercase (A1B2C3). These represent the same value but fail string comparison. Always check the API docs and normalize accordingly.
  • Replay attacks. HMAC proves authenticity but not freshness. Without a timestamp or nonce in the signed payload, a valid HMAC captured in transit can be replayed indefinitely. Production webhook systems always include a timestamp in the signed string and reject signatures older than 5 minutes.

Checklist: Implementing HMAC for an API or Webhook

  • Confirm which algorithm the receiving system requires (SHA-256 unless specified otherwise)
  • Confirm the expected output format (hex, standard Base64, or URL-safe Base64)
  • Determine exactly which bytes get signed โ€” full request body, specific headers, a canonical string? Get the spec precisely right
  • Confirm how the key is provided โ€” raw bytes, hex-encoded, Base64-encoded? Decode before use
  • Always encode the message to UTF-8 bytes before passing to the HMAC function
  • Include a timestamp in the signed payload and validate that the signature is not older than an acceptable window (300 seconds is standard)
  • Use constant-time comparison when verifying received signatures to prevent timing attacks
  • Rotate keys on a defined schedule and support dual-key validation during rotation windows
  • Never log the raw secret key; logging the HMAC output is fine
  • Test with a known good vector (RFC 4231 provides official SHA-256 test cases)

Real-World Integrations Where You Will Use This Tool

GitHub delivers webhook payloads with an X-Hub-Signature-256 header containing sha256=<hex-hmac> of the JSON body signed with your webhook secret. Stripe uses a similar pattern: t=<timestamp>.<hex-hmac> over a concatenated string of the timestamp, a dot, and the raw body. AWS Signature Version 4 builds a canonical request string and signs it with HMAC-SHA-256 in four nested steps. Shopify, Twilio, SendGrid, Slack, and Discord all follow variations of the same pattern. Once you understand the core mechanic โ€” derive bytes, sign with key, compare outputs โ€” every new integration is just reading the docs to find what goes into the message string.

Security Boundary Reminder

HMAC security depends entirely on the secrecy of the key. A 256-bit random key is unguessable; a short dictionary word is not. Use a cryptographically random key of at least 32 bytes (256 bits) generated by a secure random number generator โ€” openssl rand -hex 32 on the command line, or crypto.randomBytes(32) in Node.js. Store it in an environment variable or secrets manager, never hardcoded in source. This browser tool processes everything locally so your key never leaves your machine โ€” but the same discipline applies to wherever you use HMAC in production.

FAQ

What is the difference between HMAC and a regular hash like SHA-256?
A regular hash (like SHA-256 applied directly to a message) has no secret ingredient โ€” anyone who knows the message can compute the same hash. HMAC mixes a secret key into the computation using a specific double-hash construction defined in RFC 2104. Without the key, an attacker cannot forge a valid HMAC even if they know the message. Regular SHA-256 is also vulnerable to length-extension attacks; the HMAC construction eliminates this by design.
Is HMAC-SHA-1 still safe to use?
For HMAC specifically, yes โ€” HMAC-SHA-1 is still considered computationally secure in 2025 when the key remains secret, because the known SHA-1 collision attacks do not apply to the HMAC construction. The practical reason to avoid it is ecosystem momentum: every new API spec uses SHA-256 or SHA-512, so choosing SHA-1 now means a migration later. Use it only if you are forced to match an existing system that requires it.
Why does my HMAC not match the one generated by the server?
The most common causes in order: (1) the message bytes differ โ€” check for trailing newlines, different character encodings, or extra whitespace; (2) the key is being used incorrectly โ€” some APIs provide a hex or Base64-encoded key that must be decoded to raw bytes before use, rather than passed as an ASCII string; (3) output format mismatch โ€” hex vs Base64, or lowercase vs uppercase hex; (4) the message being signed is not the raw body but a canonical string built from specific fields. Verify each of these against the API documentation.
Can I use this tool to verify a webhook signature I received?
Yes. Paste the exact webhook payload (byte-for-byte, no reformatting), enter the webhook secret key, select the algorithm the provider uses (SHA-256 for GitHub, Stripe, Shopify), and choose hex output. Compare the result to the signature in the webhook header โ€” for GitHub it appears after 'sha256=', for Stripe after the dot in the header value. If they match, the webhook is authentic. Make sure you paste the raw body without any JSON prettification, as whitespace changes the hash.
Should I use hex or Base64 output for my HMAC?
Use whichever format the receiving system expects โ€” both encode the same underlying bytes. Hex (64 characters for SHA-256) is more human-readable and used by AWS, GitHub, and most command-line tooling. Base64 (44 characters for SHA-256) is more compact and preferred by Stripe, JWT, and many mobile-friendly APIs. If the target system uses URL-safe Base64, check whether the output needs '+' replaced with '-' and '/' replaced with '_', and whether the trailing '=' padding should be stripped.
How long should my HMAC secret key be?
RFC 2104 recommends the key be at least as long as the hash output โ€” so 32 bytes (256 bits) for HMAC-SHA-256 and 64 bytes for HMAC-SHA-512. In practice, a 32-byte cryptographically random key is strong enough for any HMAC variant. Generate it with 'openssl rand -hex 32' or 'openssl rand -base64 32' on the command line. Never use a short password or dictionary phrase directly as the HMAC key without first running it through a proper key derivation function like PBKDF2 or Argon2.