← Back to the tool

Foundations · Under the hood

HMAC sign & verify

What each button in the tool actually computes, step by step — with the real formulas.

Turning one secret into two padded keys

HMAC first pads (or, if it's longer than one block, hashes down) your secret to SHA-256's 64-byte block size, producing K′. That padded key is then XORed with two fixed constants — ipad (0x36 repeated) and opad (0x5c repeated) — producing two different derived keys from the one secret you typed.

Two nested hashes

The inner hash covers the padded-and-XORed key plus your actual message. The outer hash covers the padded-and-XORed key (with the other constant) plus that inner result. The hex string labeled "Tag" is the output of the outer hash — a single 32-byte value.

HMAC(K,m)=H((Kopad)H((Kipad)m))\mathrm{HMAC}(K, m) = H\big((K' \oplus \mathrm{opad}) \,\|\, H((K' \oplus \mathrm{ipad}) \,\|\, m)\big)

Why not just H(secret ‖ message)?

The simpler-looking H(secret ‖ message) is vulnerable to length-extension attacks, covered in detail in the Hash functions module — an attacker who knows H(secret ‖ message) can compute H(secret ‖ message ‖ extra) without ever learning the secret. HMAC's nested double-hash construction closes that gap; it's not a stylistic choice.

What the Verify button actually checks

It recomputes HMAC(secret, message) from scratch, using whatever is currently in the message and secret fields, and compares the result to the tag you provided. Production systems use a constant-time comparison for this exact step — comparing byte by byte and stopping at the first mismatch leaks timing information about how many leading bytes matched, the same class of issue covered in the side-channel module. This demo uses a simple equality check for clarity.

Now try it

Back to HMAC sign & verify

Compute a real HMAC-SHA256 over a message and secret, then see why changing even one bit of the message makes verification fail.