正在加载,请稍候…

HMAC Explained: Message Authentication with a Secret Key

Learn what HMAC is, how it differs from regular hashing, and when to use it for API authentication and data integrity.

What Is HMAC?

HMAC (Hash-based Message Authentication Code) is a specific type of message authentication code involving a cryptographic hash function and a secret cryptographic key. It combines the power of a hash function (data integrity) with a shared secret key (authenticity), providing both in a single compact output.

HMAC was standardized in RFC 2104 and is used everywhere from AWS request signing to webhook verification on GitHub and Stripe.

Why Not Just Hash the Message?

If you simply hash a message and send both together, an attacker can:

  1. Intercept the message and hash.
  2. Modify the message.
  3. Compute a new hash of the modified message.
  4. Replace both — the receiver has no way to detect tampering.

HMAC prevents this because computing a valid MAC requires the secret key. Without the key, an attacker cannot forge a valid MAC for a modified message.

How HMAC Works

HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m))

Where:

  • H = hash function (SHA-256, SHA-512, etc.)
  • K = secret key (padded to block size as K')
  • m = message
  • opad = outer padding (0x5c repeated)
  • ipad = inner padding (0x36 repeated)

The key is processed twice: once mixed into the inner hash, and again into the outer hash. This double-keying structure prevents length-extension attacks that affect plain hashing.

HMAC vs Plain Hashing

Property Plain Hash HMAC
Key required
Integrity verification
Authenticity verification
Forgeable without key
Resistance to length extension ❌ (SHA-2)

Choosing a Hash Algorithm for HMAC

HMAC Variant Security Common Use
HMAC-MD5 Weak Legacy only
HMAC-SHA1 Acceptable Git, older protocols
HMAC-SHA256 ✅ Strong AWS Signature V4, most APIs
HMAC-SHA512 ✅ Very strong High-security requirements

HMAC-SHA256 is the modern standard for most applications.

Real-World HMAC Applications

Webhook Signature Verification

When GitHub, Stripe, or Shopify sends a webhook to your server, they include an HMAC signature in the request headers. You verify it by computing the HMAC of the request body with your secret key and comparing.

// Verify a GitHub webhook
const crypto = require('crypto');

function verifySignature(secret, payload, signature) {
  const computed = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(computed),
    Buffer.from(signature)
  );
}

Note the use of timingSafeEqual — comparing MAC values character by character leaks timing information that attackers can exploit. Always use constant-time comparison.

AWS Signature Version 4

Every AWS API request is signed with HMAC-SHA256 using a derivative of your secret access key:

SigningKey = HMAC(HMAC(HMAC(HMAC("AWS4" + SecretKey, Date), Region), Service), "aws4_request")
Signature = HMAC(SigningKey, StringToSign)

This multi-level derivation means even if one request's signing key is somehow exposed, it cannot be used to sign requests for other dates, regions, or services.

JWT HS256 Signing

When a JWT uses the HS256 algorithm, it's signed with HMAC-SHA256:

const signature = HMAC_SHA256(secret, base64url(header) + '.' + base64url(payload));

Cookie and Session Integrity

Express.js and similar frameworks sign cookies with HMAC to prevent tampering:

// Express cookie-session uses HMAC internally
app.use(session({
  secret: 'your-secret-key',  // Used for HMAC signing
  resave: false,
  saveUninitialized: true
}));

Security Considerations

  1. Key length — Use at least 32 bytes (256 bits) for HMAC-SHA256 keys.
  2. Key rotation — Rotate HMAC keys periodically. When rotating, support a brief transition window where both old and new keys are valid.
  3. Constant-time comparison — Always compare MACs in constant time to prevent timing attacks.
  4. Key storage — Never hard-code HMAC secrets in source code. Use environment variables or a secrets manager.

Using This Tool

Enter your message and secret key, select the hash algorithm (MD5, SHA-1, SHA-256, SHA-384, SHA-512), and the tool computes the HMAC in your browser. You can output the result in hex (default), Base64, or Base64URL format.

→ Try the HMAC Generator