Create HMAC-SHA256 signatures locally with the HMAC Generator. Your secret and message never leave your browser.
What HMAC actually is
HMAC (Hash-based Message Authentication Code) is a keyed hash. It takes a secret and a message and produces a fixed-size signature that depends on both.
Because the secret is mixed into the computation, only someone who knows the secret can produce or verify the signature. That makes HMAC the workhorse of API authentication, webhook verification, and signed payloads.
HMAC is not encryption: the signature hides nothing, and anyone who captures a signed request can still read the message. HMAC proves authentication and integrity — that the message came from someone holding the secret and was not altered.
When you need HMAC signatures
The most common cases are webhooks and API requests. When a provider posts an event to your endpoint, the signature confirms the payload is genuine before you act on it. When a client calls your API, a signed request proves the caller holds the secret without sending it.
- Webhooks: the receiver verifies the signature to prove the payload came from the sender
- API authentication: clients sign requests with a shared secret instead of sending a password
- Integrity checks: detect message tampering between services
- Replay protection: sign a message that includes a timestamp or nonce
Create an HMAC-SHA256 signature: step by step
Canonicalization is where integrations usually break. When I first set up webhook verification, every signature failed because the sender added a trailing newline my side did not expect. The fix was agreeing on the exact bytes: the receiver must rebuild the exact string you signed, with the same JSON key order, escaping, and line endings.
// Example: canonical string and HMAC-SHA256 in Node.jsconst canonical = [method, path, timestamp, body].join('\n');const signature = crypto.createHmac('sha256', secret).update(canonical).digest('hex');- Open the HMAC Generator in your browser.
- Select SHA-256 as the algorithm.
- Paste your secret key into the key field. Generate one with the Password Generator if needed.
- Paste the exact message or payload you want to sign, byte for byte.
- Copy the generated signature and attach it to the request, for example as an Authorization or X-Signature header.
Warning: The signature changes if even one byte of the message changes, and the exact string you sign must match what the other side signs. Line endings and whitespace count.
Verify signatures safely on the receiving side
Verification is a second HMAC computation with the same secret and message, compared against the received signature.
The comparison must be constant-time. A plain string comparison can leak timing information that helps attackers forge signatures.
A plain comparison stops at the first differing character, so response time reveals how close the attacker's guess is. Enough samples recover the signature byte by byte, while a constant-time comparison always runs the same operations.
// Node.js: constant-time comparisonconst crypto = require('crypto');const expected = Buffer.from(signature, 'hex');const received = Buffer.from(given, 'hex');const valid = expected.length === received.length && crypto.timingSafeEqual(expected, received);Common HMAC mistakes
- Hard-coding the secret in client-side code where everyone can read it
- Signing the body but not the method, path, and timestamp, enabling replay attacks
- Using == or plain string comparison for signature verification
- Reusing the same secret across environments or never rotating it
- Feeding the signature into a tool that logs the secret alongside the message
- Building the canonical string differently from the receiver, like different JSON key order or trailing whitespace
- Comparing signature bytes in different encodings, such as hex on one side and base64 on the other
FAQ
Q.Should the HMAC secret live in client code?
A.No. Anything shipped to a browser can be read — open the developer tools and the secret is right there. Keep secrets in server-side environment variables or a secret manager, and sign requests server-side. Client-side signing only deters casual tampering; a browser tool is for testing during development, not for protecting a production endpoint.
Q.Is HMAC encryption?
A.No. HMAC is a keyed hash for authentication and integrity: it proves who sent the message and that it did not change, but the message itself stays readable. Anyone who sees the signed request can read its full contents. When confidentiality matters too, encrypt the payload with AES-GCM, or rely on TLS in transit.
Q.Can an HMAC signature be reversed?
A.No practical way exists. HMAC is one-way, and the secret never appears in the signature, so collecting many message-signature pairs does not reveal it. The effort shifts to guessing the secret, which is why key size matters: a 256-bit random secret is far beyond practical brute force. Protect the secret itself and rotate it on a schedule.
References
- RFC 2104 – HMAC: Keyed-Hashing for Message Authentication: https://www.rfc-editor.org/rfc/rfc2104
- NIST FIPS 198-1 – The Keyed-Hash Message Authentication Code (HMAC): https://csrc.nist.gov/pubs/fips/198-1/final
- RFC 7515 – JSON Web Signature (JWS): https://www.rfc-editor.org/rfc/rfc7515
- OWASP Secrets Management Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html
Create a signature
HMAC-SHA256, SHA-1, or MD5 in your browser; your key never leaves the device.
Sign what you send, verify in constant time
Sign the exact bytes both sides expect, attach the signature as a header, and reject requests with old timestamps.
Compare signatures with a constant-time function, keep the secret server-side, and generate signatures locally with the HMAC Generator.
Start small: sign one endpoint, verify it on the receiving side, and rotate the key once the flow is proven. The mechanics are simple once the canonical string is agreed upon.