What does an HMAC generator do?
An HMAC generator combines a message, a secret key and a hash function into a short tag called a message authentication code. Anyone holding the same key can recompute the tag and confirm the message wasn't altered. Without the key, producing a valid tag is infeasible. This tool computes HMAC with SHA-1, SHA-256, SHA-384 or SHA-512.
HMAC is specified in RFC 2104. The construction hashes twice: first the key mixed with an inner pad plus the message, then the key mixed with an outer pad plus that first result. Keys shorter than the hash's block size are padded with zeros, and longer keys are hashed down first. That nesting is what makes HMAC safe where a naive sha256(key + message) is not, because SHA-256 on its own allows length-extension attacks.
How to compute an HMAC here
- Paste the exact message into the Message box.
- Type or paste the key into the Secret key box.
- Choose the hash algorithm. SHA-256 is selected by default.
- Click Generate and copy the lowercase hex tag.
Both fields are encoded as UTF-8 and nothing is trimmed, so a space at the end of the key produces a different tag. With the message The quick brown fox jumps over the lazy dog, the key key gives f7bc83f4...2d1a3cd8 under SHA-256, while key (with a trailing space) gives c5c9b038...fe75aa97.
The computation goes through SubtleCrypto.sign(), the browser's native implementation, which is why only the four hashes Web Crypto supports are offered. There's no HMAC-MD5, HMAC-SHA224 or HMAC-SHA3 option.
Verified against the RFC test vectors
RFC 4231 publishes HMAC-SHA-2 test cases, and its test case 2 is one you can type: the key is Jefe and the data is what do ya want for nothing?. The same inputs appear in RFC 2202 for HMAC-SHA1. This tool returns:
SHA-1: effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
SHA-256: 5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843
SHA-384: af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649
SHA-512: 164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737
All four match the published values. You can reproduce the SHA-256 line with OpenSSL:
printf '%s' 'what do ya want for nothing?' | openssl dgst -sha256 -hmac Jefe
| Algorithm | Block size | Tag length | Hex characters |
|---|---|---|---|
| HMAC-SHA1 | 64 bytes | 160 bits | 40 |
| HMAC-SHA256 | 64 bytes | 256 bits | 64 |
| HMAC-SHA384 | 128 bytes | 384 bits | 96 |
| HMAC-SHA512 | 128 bytes | 512 bits | 128 |
Where you'll meet HMAC
Webhooks. GitHub signs each delivery with HMAC-SHA256 of the raw payload and sends it in the X-Hub-Signature-256 header, prefixed with sha256=. Its webhook validation guide also tells you to compare signatures with a constant-time function rather than ==, so response timing doesn't leak how many characters matched.
Signed API requests. Many APIs have the client HMAC a canonical string (method, path, timestamp, body hash) and send the tag in a header.
JSON Web Tokens. The HS256, HS384 and HS512 algorithms in RFC 7518 are HMAC with SHA-256, SHA-384 and SHA-512. JWTs carry the tag in Base64url, not hex, so the output here won't look identical even when the bytes agree.
When the tags don't match
| Symptom | Likely cause |
|---|---|
| Every tag differs from the server's | Wrong algorithm, or the key has a stray space or newline |
| Matches for some requests, not others | You're hashing parsed-and-reprinted JSON instead of the raw body |
Server value is 64 hex chars plus sha256= |
Strip the prefix before comparing |
Server value ends in = or uses - and _ |
It's Base64 or Base64url, not hex |
| Key looks like hex but still fails | The service decodes the key to bytes; this tool uses it as text |
Choosing a key
The key is the whole security of an HMAC, so it has to be secret and unpredictable. RFC 2104 discourages keys shorter than the hash output (32 bytes for SHA-256). A long random string from the password generator works as a text key, or use the random hex generator if both sides will treat the hex string itself as the key.
An HMAC is a keyed checksum. It doesn't hide the message, and it isn't a password-hashing scheme. For an unkeyed fingerprint of text, use the SHA-256 hash generator. For a MAC built on SHA-3 rather than SHA-2, look at KMAC, covered on the SHA3-256 generator page.
Last updated