Everything, Everywhere
Verified Specification | Standardized Formulas | Instant Precision
Secure & Private (Zero Data Retention) Free Access • No Sign-Up
RFC 2104 HMAC Engine Hardware WebCrypto Webhook Verification Matrix Constant-Time Auditor

HMAC Generator & Webhook Signature Verification Studio

Generate hardware-accelerated HMAC message authentication digests (SHA-256, SHA-512, SHA-384, SHA-1, MD5) directly in browser memory. Verify production webhook signatures from Stripe, GitHub, Shopify, and Slack, and audit constant-time comparison algorithms against timing side-channel attacks.

Key length: 36 characters (288 bits UTF-8)
0 bytes
< 1 ms
WebCrypto Latency
256 bits
Digest Bit Length
32 bytes
Binary Size
2^128
Collision Resistance

Cryptographic Architecture Showdowns

HMAC vs Digital Signatures (RSA / ECDSA)

HMAC (Symmetric): Both sender and receiver share the identical secret key. Extremely fast (millions of ops/sec), zero asymmetric math overhead. However, anyone who can verify the signature can also forge it (no non-repudiation).

RSA/ECDSA (Asymmetric): The sender signs with a private key; the receiver verifies with a public key. The receiver cannot forge signatures. Suitable for public distributed APIs, but computationally 100x to 1,000x heavier.

HMAC vs Naive Hash(Key || Message)

Length Extension Attack: Merkle-Damgård hash functions (MD5, SHA-1, SHA-256) process data in sequential blocks. If an API verifies H(secret || data), an adversary knowing the length of the secret can append malicious commands (e.g. &admin=true) and compute the exact valid hash without knowing the secret.

RFC 2104 Nested Hash: HMAC computes H((K ^ opad) || H((K ^ ipad) || M)). The outer hash completely seals the internal state, rendering length-extension attacks mathematically impossible.

HMAC-SHA256 vs HMAC-SHA512

HMAC-SHA256: Uses 32-bit words with a 256-bit digest and 128-bit collision resistance. Universally supported by Stripe, GitHub, AWS, and Cloudflare.

HMAC-SHA512: Uses 64-bit words with a 512-bit digest. On modern 64-bit server processors (x86_64 and ARM64), SHA-512 frequently executes 20% to 50% faster per byte than SHA-256 for large payloads while offering a 256-bit collision security margin.

Constant-Time (timingSafeEqual) vs String ===

Naive String Equality: Returns false at index 0 if the first character mismatches. A remote attacker sending statistically grouped candidate payloads will observe slight nanosecond latency increases when guessing the correct first byte, allowing brute-force in O(N × 16) attempts.

timingSafeEqual: Always iterates across all buffer bytes, performing bitwise XOR operations (diff |= a[i] ^ b[i]), returning zero elapsed timing information to potential eavesdroppers.

5 Fatal Traps in Webhook Authentication

Trap 1: JSON Parsing Before Webhook Verification
Standard web server middleware (e.g. express.json() or Django request parsers) parses incoming bytes into a JSON dictionary. If you calculate the HMAC on JSON.stringify(req.body), key ordering, space indentation, or Unicode escapes will not match the sender's exact bytes, causing 100% false signature rejection. Always preserve the raw request buffer.
Trap 2: Omitting Timestamp Tolerance (Replay Attacks)
A valid HMAC signature proves the payload is untampered, but if your server does not verify an accompanying timestamp header (e.g. t=1774137600), an attacker intercepting the request can replay the identical valid packet hundreds of times, triggering duplicate invoice fulfillments or credit top-ups.
Trap 3: Leaking Secrets to Client-Side Bundles
HMAC is a symmetric algorithm. Anyone with the secret key can generate valid signatures. Never expose webhook secrets or API signing keys in frontend JavaScript bundles, mobile app binaries, or public GitHub repositories.
Trap 4: Character Encoding Mismatches (UTF-8 vs ASCII)
Passing multi-byte Unicode strings (such as emojis or non-Latin characters) into cryptographic functions without explicit UTF-8 byte encoding produces differing byte streams between systems. Always encode both keys and messages via standard UTF-8 byte representations.
Trap 5: Truncating Signatures Incorrectly
Some legacy protocols truncate HMAC digests to 128 or 160 bits. Never truncate arbitrary hex string characters manually without ensuring both ends of the protocol use identical constant-time slice bounds.

Frequently Asked Technical Questions

How does HMAC (RFC 2104) prevent length-extension attacks?

Merkle-Damgård hash functions (MD5, SHA-1, SHA-256) update an internal state block by block. If an API uses a naive concatenation Hash(secret || message), an attacker who intercepts the hash and knows the message length can resume the hash state to append malicious data. HMAC uses a two-pass nested construction: H((K ^ opad) || H((K ^ ipad) || M)). Because the inner hash output is digested again by the outer hash with a separate key pad, the internal state of the inner hash is permanently obscured.

Why is crypto.timingSafeEqual mandatory for webhook verification?

Standard string equality (=== or strcmp) aborts execution on the first mismatched byte. Attackers can measure the response time of thousands of requests using high-resolution timers. If a candidate byte causes the server to take 20 nanoseconds longer before returning 403 Forbidden, the attacker knows that byte matched. Repeating this process for each position cracks 32-byte signatures in linear time. Constant-time comparison ensures identical execution time regardless of mismatch location.

How do I access raw request bytes in Node.js Express for Stripe or GitHub?

In Express, pass a custom verify function to the JSON body parser: app.use(express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }));. Then, when calculating the HMAC digest, pass req.rawBody directly to hmac.update() instead of converting or re-stringifying req.body.

What is the recommended secret key length for HMAC-SHA256?

RFC 2104 recommends that the secret key length be at least equal to the hash function's output size. For HMAC-SHA256, the secret key should be at least 256 bits (32 bytes). Keys longer than the hash block size (64 bytes for SHA-256) are automatically pre-hashed to 32 bytes using SHA-256.

Can HMAC be reversed or decrypted to recover the original message?

No. HMAC is a one-way message authentication code, not an encryption cipher. It computes a fixed-length cryptographic digest that irreversibly summarizes the input data. It is mathematically impossible to decrypt an HMAC digest to recover the original message or the secret key.

Sponsored Utility
While You're Here
Sponsored Recommendations
Advertisement