HMAC Generator
Generate HMAC signatures using SHA-256, SHA-384, SHA-512, or SHA-1 with your secret key. Output in hex or base64 format, all in your browser.
HMAC (Hash-based Message Authentication Code) verifies both the integrity and authenticity of a message using a secret key. This tool generates HMAC signatures using SHA-256, SHA-384, SHA-512, or SHA-1, with output in hex or base64 format. All computation uses the browser's Web Crypto API - your key and message never leave your device.
About HMAC Generator
How HMAC Works
HMAC combines a secret key with a message and runs them through a hash function in a specific way: HMAC(K, m) = H((K' XOR opad) || H((K' XOR ipad) || m)). The double hashing with inner and outer padding prevents length extension attacks that affect plain hash(key + message) constructions.
| Component | Purpose |
|---|---|
| Secret key | Known only to sender and receiver - proves authenticity |
| Message | The data being signed (API request body, webhook payload, etc.) |
| Hash function | Produces fixed-length output (SHA-256, SHA-512, etc.) |
| Inner padding (ipad) | XOR with 0x36 - used in the inner hash |
| Outer padding (opad) | XOR with 0x5c - used in the outer hash |
HMAC vs Plain Hashing
| Property | Hash (SHA-256) | HMAC (HMAC-SHA-256) |
|---|---|---|
| Inputs | Message only | Message + secret key |
| Anyone can compute? | Yes | No - requires the secret key |
| Proves authenticity? | No | Yes - only key holders can generate valid signatures |
| Proves integrity? | Yes (if you trust the hash source) | Yes (guaranteed by the key) |
| Vulnerable to length extension? | Yes (SHA-256, SHA-512) | No - HMAC construction prevents this |
Supported Algorithms
| Algorithm | Output (hex) | Output (base64) | Status |
|---|---|---|---|
| HMAC-SHA-256 | 64 characters | 44 characters | Recommended - most widely used |
| HMAC-SHA-384 | 96 characters | 64 characters | Good - larger output |
| HMAC-SHA-512 | 128 characters | 88 characters | Good - maximum security margin |
| HMAC-SHA-1 | 40 characters | 28 characters | Legacy only - do not use for new systems |
Where HMAC Is Used
| Service | Use Case | Algorithm | How It Works |
|---|---|---|---|
| AWS Signature V4 | API request signing | HMAC-SHA-256 | Signs request method, headers, and body with derived key |
| Stripe webhooks | Payload verification | HMAC-SHA-256 | Signs timestamp + payload with endpoint secret |
| GitHub webhooks | Payload verification | HMAC-SHA-256 | Signs raw body with webhook secret (X-Hub-Signature-256) |
| Slack | Request verification | HMAC-SHA-256 | Signs timestamp:body with signing secret |
| JWT (HS256) | Token signing | HMAC-SHA-256 | Signs header.payload with shared secret |
| TOTP (2FA codes) | One-time passwords | HMAC-SHA-1 | Signs time-based counter with shared secret |
| OAuth 1.0 | Request signing | HMAC-SHA-1 | Signs base string with consumer + token secrets |
Verifying a Webhook Signature
Most webhook providers send a signature in a header (like X-Hub-Signature-256). To verify, you compute the HMAC of the raw request body using your webhook secret and compare it to the received signature.
| Step | Action |
|---|---|
| 1 | Get the signature from the request header |
| 2 | Get the raw request body (before any parsing) |
| 3 | Compute HMAC of the body using your secret key |
| 4 | Compare computed signature to received signature using constant-time comparison |
| 5 | Reject the request if signatures do not match |
Always use constant-time comparison (like crypto.timingSafeEqual in Node.js) to prevent timing attacks. A regular string comparison (===) leaks information about which characters match.
Key Length Recommendations
| Algorithm | Recommended Key Length | Why |
|---|---|---|
| HMAC-SHA-256 | 32+ bytes (256 bits) | Match the hash output length for optimal security |
| HMAC-SHA-512 | 64+ bytes (512 bits) | Match the hash output length |
| Any HMAC | At least 16 bytes (128 bits) | Absolute minimum to prevent brute force |
Keys shorter than the hash block size are padded, and keys longer than the block size are hashed first. Using a key that matches the hash output length gives the best security without unnecessary overhead.
For non-keyed hashing (file checksums, data fingerprinting), the Hash Generator supports SHA-256, SHA-512, and MD5. For data encryption rather than signing, the Encryption/Decryption Tool handles AES encryption. All computation runs in your browser via the Web Crypto API.
Worked Example: Verifying a GitHub Webhook
GitHub signs webhook payloads with HMAC-SHA-256 using the secret you configure per webhook endpoint. The signature is delivered in the X-Hub-Signature-256 header as sha256=<hex>. Say your webhook secret is It's a Secret to Everybody and the raw request body is Hello, World!. The expected HMAC-SHA-256 is 757107ea0eb2509fc211221cce984b8a37570b6d7586c22c46f4379c8b043e17 (this is the canonical example in GitHub's webhook documentation). Your server recomputes HMAC-SHA-256 over the exact raw body using the same secret and checks it matches, using a constant-time comparison. If the bytes differ anywhere - whether the attacker tampered with the payload or sent a wrong secret - the signatures will not match and the request is rejected. Never JSON-parse the body before verifying; any whitespace or ordering change will invalidate the signature.
What Are the RFC and NIST Standards Behind HMAC?
HMAC is defined by RFC 2104 (published 1997 by Krawczyk, Bellare, and Canetti) and standardised by NIST in FIPS 198-1 (2008). The construction is deliberately simple so it can be built on top of any iterated hash function without modifying the hash itself. The security proof by Bellare (2006) shows HMAC is a secure pseudo-random function as long as the underlying compression function is a PRF - a weaker assumption than full collision resistance, which is why HMAC-SHA-1 is still considered safe against known attacks even though plain SHA-1 is broken for collision resistance (SHAttered, 2017).
| Standard | Year | Scope |
|---|---|---|
| RFC 2104 | 1997 | Original HMAC specification with ipad/opad construction |
| FIPS 198-1 | 2008 | NIST formal standard, approved for US government use |
| RFC 4231 | 2005 | Test vectors for HMAC-SHA-224, SHA-256, SHA-384, SHA-512 |
| RFC 6234 | 2011 | US Secure Hash Algorithms (SHA and SHA-based HMAC) |
| NIST SP 800-107 Rev 1 | 2012 | Recommendation for applications using approved hash algorithms |
Common HMAC Mistakes That Break Production Systems
The HMAC construction is well-defined, but integrations fail for predictable reasons. Most real-world HMAC bugs fall into a handful of categories - and almost all of them are implementation errors, not weaknesses in the algorithm itself.
| Mistake | What Goes Wrong | Fix |
|---|---|---|
| Parsing the body before verifying | JSON reformatting changes bytes, signature fails | Capture raw body bytes first, verify, then parse |
Using === or strcmp | Timing attacks leak which characters match | Use crypto.timingSafeEqual (Node), hmac.compare_digest (Python) |
| Hex vs base64 mismatch | Signatures encoded differently on each side | Agree on one encoding and normalise both sides |
| Trimming whitespace from body | Trailing newline in the payload is significant | Never strip bytes before HMAC |
| Using the key as a hash seed | sha256(key + message) is vulnerable to length extension | Always use the proper HMAC construction |
| Hardcoding secrets in source control | Git history permanently leaks the key | Load from env vars or a secret manager, rotate if exposed |
| Not including a timestamp | Replay attacks reuse a valid signature | Sign timestamp + body and reject stale timestamps (Slack uses 5 minutes) |
| Logging the raw signature | Signatures can appear in error logs, CDN logs, etc. | Scrub signature headers from log output |
Is HMAC-SHA-1 Still Safe to Use?
HMAC-SHA-1 remains cryptographically safe for message authentication despite SHA-1 itself being broken for collision resistance. The SHAttered attack (Google, 2017) and Shambles (2020) demonstrate practical collision attacks against plain SHA-1, but HMAC's security relies on the underlying hash being a pseudo-random function under a secret key - a property that still holds for SHA-1. NIST SP 800-131A allows HMAC-SHA-1 for message authentication, though NIST SP 800-107 recommends migration to SHA-2 family for new systems. TOTP (RFC 6238) and OAuth 1.0 still specify HMAC-SHA-1, and upgrading these protocols mid-flight would break existing 2FA apps and millions of integrations. For new systems, HMAC-SHA-256 is the sensible default: it removes the SHA-1 footnote from security reviews at effectively zero performance cost on modern CPUs with SHA extensions.
Performance: Is HMAC-SHA-512 Always Slower?
Not necessarily. On 64-bit CPUs, SHA-512 operates on 64-bit words natively while SHA-256 operates on 32-bit words, so SHA-512 often matches or beats SHA-256 on long inputs. The picture changed with Intel SHA Extensions (Goldmont, 2016+) and ARMv8 Crypto Extensions, which include hardware acceleration for SHA-256 but not SHA-512. On modern x86-64 server CPUs with SHA-NI, SHA-256 is roughly 2-3x faster than SHA-512 for small inputs; on pre-SHA-NI hardware or ARM without extensions, SHA-512 can be faster. For webhook or API signing workloads where payloads are kilobytes at most, the difference is negligible - pick SHA-256 for ecosystem compatibility and move on.
HMAC vs Digital Signatures: When to Use Which?
HMAC uses a shared secret - both sender and receiver hold the same key. Digital signatures (RSA, ECDSA, Ed25519) use asymmetric keys: the sender signs with a private key and anyone can verify with the public key. HMAC is far faster (by a factor of 100-1000x) and produces smaller signatures, but it cannot prove to a third party who signed a message because both parties could have generated any given signature. Use HMAC for server-to-server integrations where both sides are trusted (webhooks, API auth, session cookies). Use digital signatures when non-repudiation matters - code signing, TLS certificates, blockchain transactions, document signing - or when the verifier cannot be trusted with the signing key.
Sources
- IETF RFC 2104 - HMAC: Keyed-Hashing for Message Authentication
- NIST FIPS 198-1 - The Keyed-Hash Message Authentication Code (HMAC)
- IETF RFC 4231 - Identifiers and Test Vectors for HMAC-SHA-224/256/384/512
- GitHub Docs - Validating Webhook Deliveries
- Stripe Docs - Verifying Webhook Signatures Manually
- Slack API - Verifying Requests from Slack
- MDN - SubtleCrypto.sign()
Frequently Asked Questions
What is HMAC used for?
HMAC is used to verify both the integrity and authenticity of a message. Common use cases include API request signing (like AWS Signature V4), webhook payload verification (like Stripe or GitHub webhooks), JWT token signing, and secure cookie generation.
Is HMAC the same as hashing?
No. A regular hash like SHA-256 only takes a message as input and anyone can compute it. HMAC also requires a secret key, so only parties who know the key can generate or verify the signature. This prevents tampering by third parties.
Which HMAC algorithm should I choose?
HMAC-SHA-256 is the most widely used and recommended for most applications. HMAC-SHA-512 offers a larger output if needed. HMAC-SHA-1 is considered legacy and should only be used for backward compatibility.
Is my secret key sent to a server?
No. All HMAC computation happens entirely in your browser using the Web Crypto API (SubtleCrypto.sign). Your key and message never leave your device.
Related Tools
Link to this tool
Copy this HTML to link to this tool from your website or blog.
<a href="https://toolboxkit.io/tools/hmac-generator/" title="HMAC Generator - Free Online Tool">Try HMAC Generator on ToolboxKit.io</a>