diagram.mmd — flowchart
HMAC Signing Process flowchart diagram

HMAC (Hash-based Message Authentication Code) is a symmetric message authentication mechanism that combines a cryptographic hash function with a shared secret key to produce a signature that proves both the integrity and authenticity of a message.

Unlike asymmetric digital signatures, HMAC uses the same key for both signing and verification. This makes it significantly faster and simpler to implement, but it requires that both parties share the secret key securely in advance. HMAC is widely used for API authentication, webhook signature verification, JWT tokens (HS256 variant), and cookie integrity checks.

The HMAC algorithm works by applying the hash function twice with key-derived pads. Specifically, HMAC(K, m) = H((K ⊕ opad) || H((K ⊕ ipad) || m)) where H is the hash function (commonly SHA-256), K is the secret key, opad is the outer padding (0x5c repeated), and ipad is the inner padding (0x36 repeated). In practice, you never implement this manually — all crypto libraries expose an HMAC function directly.

During signing, the sender runs the message and secret key through HMAC-SHA256 to produce a fixed-length signature (32 bytes for SHA-256). This signature is transmitted alongside the message, typically as a hex string or base64-encoded value in a header like X-Signature or as part of an Authorization header.

On the verification side, the receiver independently computes HMAC of the received message using the same shared secret, then compares their computed HMAC to the received HMAC using a constant-time comparison function. Using a constant-time comparison is critical — a naive string equality check is vulnerable to timing attacks where an attacker can deduce the correct HMAC byte-by-byte by measuring response times.

HMAC does not provide non-repudiation (because both parties have the same key, either could have produced the signature), unlike asymmetric Digital Signature Workflow. For webhook use cases, see API Request Signing.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

HMAC (Hash-based Message Authentication Code) is a symmetric mechanism that combines a cryptographic hash function with a shared secret key. It produces a fixed-length authentication tag that proves a message was created by a party holding the shared secret and that the message content has not been altered.
A standard string comparison short-circuits as soon as it finds a mismatching byte, leaking timing information an attacker can use to deduce the correct HMAC byte-by-byte. Constant-time comparison always examines every byte before returning, preventing this timing side-channel attack.
Use HMAC when both parties share a secret key and non-repudiation is not required — for example, webhook verification, JWT HS256 signing within a single service boundary, or API authentication between services you control. Use asymmetric digital signatures when multiple independent verifiers need to validate signatures, or when you need to prove which specific party signed the message.
mermaid
flowchart TD A[Message to authenticate] --> B[Signing: combine message\nwith shared secret key] B --> C[Apply HMAC-SHA256\nalgorithm] C --> D[Produce HMAC signature\n32-byte hex or base64] D --> E[Attach signature to message\nX-Signature header or query param] E --> F[Transmit message + signature\nto recipient] F --> G[Recipient receives message + signature] G --> H[Retrieve shared secret key\nfrom secure storage] H --> I[Independently compute HMAC-SHA256\nover received message] I --> J[Constant-time comparison\ncomputed HMAC vs received HMAC] J --> K{HMACs match?} K -- Yes --> L[Message authentic and unmodified\nProceed with processing] K -- No --> M[Reject request\n401 Unauthorized]
Copied to clipboard