🧰 UtlKit

How to Use the HMAC Generator: SHA-256, SHA-384 and SHA-512 Signatures from Text or Hex Keys, in the Browser

One message and one secret, read as UTF-8 text or raw hex, signed with SHA-256, SHA-384 or SHA-512 into a hex or Base64 digest, all computed in the browser through WebCrypto.

The HMAC Generator signs one message with one secret key and prints the keyed digest. The whole computation is a browser-side WebCrypto call: the message and the key stay on the page, nothing is sent to any server, and the result is a deterministic string you can paste into a request header, a query parameter or a test vector. Start at the HMAC Generator, type The quick brown fox jumps over the lazy dog as the message, type key as the secret, keep SHA-256 and Hex selected, and press Generate: the digest prints f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8.

The four controls

Four inputs drive the digest: the message box, the secret key box with its Text/Hex toggle, the algorithm select and the output format select. The message is a multi-line text area: newlines are part of the message and get signed, so the same words on two lines sign differently from the same words joined by a space, and the UTF-8 bytes of 你好 sign as 309b75c0cbbfb27bb35b8d7b8f4adb4b9399cd54339ab5faeb8798e1b9f7f00c under the key key. The secret key is a single-line box, and its toggle decides how the string is read. The algorithm select offers SHA-256, SHA-384 and SHA-512, and the format select offers Hex and Base64. Generate is an explicit button: nothing is computed until it is pressed, and the digest appears in a read-only box with a copy button beside it.

Text keys and hex keys

In Text mode the key is read as the UTF-8 bytes exactly as typed: every character is part of the key, including a trailing space, so the key key signs abc as 9c196e32dc0175f86f4b1cb89289d6619de6bee699e4c378e68309ed97a1a6ab, while key with one trailing space signs the same abc as 0324ef70f9e605e123731b458dcdce99cf5f8d23572f604fbdabf371aedb0f68. In Hex mode the string is first stripped of all whitespace and then read as raw byte pairs, so 616263 is the three bytes 0x61, 0x62 and 0x63, not the six characters of the text 616263: under the message msg the hex key 616263 signs as eb14f17c9f056479f147adcf8020d27914f1e5971f049e75bf21a669cbd747e2, while the text key 616263 signs as 49962d2f0cde29c6a4848f8ea64575424ad42d3d108452127c0512cb88444a41. The hex string must be at least two characters long, an even length, and all hex digits; 6162635 fails the check before any crypto runs, as do odd lengths and letters outside a to f.

The three algorithms

The digest length is fixed by the algorithm: SHA-256 prints 32 bytes, which is 64 hex characters or 44 Base64 characters with a single = of padding; SHA-384 prints 48 bytes, 96 hex characters or 64 Base64 characters with no padding; SHA-512 prints 64 bytes, 128 hex characters or 88 Base64 characters with a double padding. All three are the same keyed construction over three hash functions, so switching the select changes the length and the value, not the shape of the input. The tool reproduces the RFC 4231 test vectors: with the hex key 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b and the message Hi There, SHA-256 prints b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7 and SHA-512 prints 87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854, and with the text key Jefe and the message what do ya want for breakfast?, SHA-256 prints 47f69d8f80f0a6326746beec23a9040fd533642b5ba38a99287670639d8b862a.

Hex and Base64

Hex prints the digest byte by byte in lowercase, two characters per byte, and Base64 prints the same bytes with standard padding. The two spellings carry the identical 32 bytes: the fox message under the key key is f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8 in Hex and 97yD9DBThCSxMpjmqm+xQ+9NWaFJRhdZl0edvC0aPNg= in Base64, the trailing = being padding rather than a signed character. The Jefe message prints R/adj4DwpjJnRr7sI6kED9UzZCtbo4qZKHZwY52Lhio= under SHA-256, MxTAcsyrQOuSUFsKlh1Gv2UuDowpCJfZzsFDvCo65FGJ15G5QCeCSey3RFF3dIlG under SHA-384, where the 48-byte digest fills the Base64 groups exactly and no padding appears, and af7nmi5sP0zyOeCqttVBl2h4BIXw5B/8dZckor99FGR+CncEsWts5Zi2pWU1HIhhnQ3+0nKMj8+Ja0GvkB1UCA== under SHA-512, where the 64-byte digest leaves one byte in the last group and the double = pads it. The copy button puts the printed string on the clipboard and reads Copied for two seconds.

Determinism and the input checks

The same message, key and algorithm always print the same digest: there is no salt, no timestamp and no randomness, which is what makes HMAC usable as a test vector and as a shared check between two systems. Two inputs are refused before any crypto runs: a message that is empty or whitespace only raises the enter-a-message error, and a key that is empty or whitespace only raises the enter-a-key error; a hex key that fails the hex check raises the invalid-hex error, and in all three cases the boxes keep their content for correction. Key length is otherwise unrestricted: a single-byte key signs abc as df55998f9fc33d78ac99d1d8ebc2b6e16aa076c4189946942a82b55d5dee8dc7, and a 100-byte key signs the same abc as 30f0f7f4a3d31b9750666b038c048550020795dd2743759bf83bcf5e0f125b36, because the HMAC construction first hashes an overlong key down to the hash size. One platform corner remains: the WebCrypto subtle API exists only in secure contexts, so on a page served over plain http the button raises the failure error instead of computing.

What it is not

The HMAC Generator is not a plain hash tool: for a digest of the message alone, without any key, the Hash Generator runs MD5, SHA-1 and the SHA-2 family on the text. It is not a JWT tool either: for reading, splitting and base64-decoding a token rather than signing one, the JWT Decoder does that. And it does not encrypt: the digest is a signature, not a secret container, and the AES guide covers the encryption direction. It also keeps no state beyond the four inputs: there is no history, no stored key and no memory of a previous digest, and closing the page discards the message and the secret.

Related Tools

Frequently Asked Questions

Does the HMAC Generator send the message or the key to a server?

No. The digest is computed on the page by the browser WebCrypto API from the two boxes and the two selects. The message bytes, the key bytes and the result all stay in the page; pressing Generate makes no network request, and the only thing that leaves the page is a copy you make of the printed digest.

Why do the same words give different digests?

Because the key mode reads the string differently. The text key 616263 is six UTF-8 characters and signs the message msg as 49962d2f0cde29c6a4848f8ea64575424ad42d3d108452127c0512cb88444a41, while the hex key 616263 is three raw bytes and signs the same message as eb14f17c9f056479f147adcf8020d27914f1e5971f049e75bf21a669cbd747e2. Whitespace matters the same way in text mode: a key with one trailing space signs abc as 0324ef70f9e605e123731b458dcdce99cf5f8d23572f604fbdabf371aedb0f68, different from the same key without the space.

Why is the hex key 6162635 rejected?

The hex check runs before any crypto: the string, with whitespace removed, must be at least two characters, an even length, and every character a hex digit. 6162635 has seven characters, an odd length, so it raises the invalid-hex error; a string with a letter outside a to f, or a single character, fails the same check. The error does not clear the box.

Does pressing Generate twice print two different digests?

No. HMAC is deterministic: the same message, key, algorithm and format always print the same string, because the construction has no salt, no timestamp and no randomness. That is the property that lets two systems with a shared secret check each other, and the reason the printed value can be pasted as a test vector.

Which of SHA-256, SHA-384 and SHA-512 should I pick?

The algorithm is a contract with the verifier: pick the one the counterparty or the specification expects, because a signature verified against the wrong hash will not match. The three differ in output length, 32, 48 and 64 bytes, and in the hash function inside the keyed construction. When choosing freely, SHA-256 is the most common default, and SHA-512 gives the longest digest.

Related Articles