Verify HMAC-SHA256 signatures with constant-time comparison analysis. Part of the DevTools Surf developer suite. Browse more tools in the Security / Crypto collection.
Use Cases
Verify incoming webhook payloads from Stripe, GitHub, or Shopify before processing.
Check if a received request signature matches a recomputed HMAC from the request body and shared secret.
Debug signature mismatch issues by comparing computed vs. received HMACs side by side.
Validate HMAC tokens generated by a partner API before trusting their data.
Tips
Always use constant-time comparison for HMAC verification in production code — timing attacks can reveal the correct HMAC by measuring response time differences.
Include the timestamp in the signed payload and reject HMAC-valid requests older than 5 minutes to prevent replay attacks.
Log verification failures with the truncated input hash, not the secret key, for debugging without exposing credentials.
Fun Facts
Stripe, GitHub, Shopify, and most major SaaS platforms use HMAC-SHA256 for webhook signature verification. The 2021 OWASP API Security report listed signature bypass as a top-5 API vulnerability.
Timing attacks on HMAC comparison were first demonstrated practically in 2009 against web frameworks that used string equality (==) for signature checks — some frameworks remained vulnerable for years after disclosure.
Node.js's crypto.timingSafeEqual() was added in v6.6.0 (2016) specifically to make constant-time comparison easy after timing attack vulnerabilities were reported in several popular npm authentication packages.
FAQ
Why does my HMAC not match even though the key is correct?
Common causes: the payload has trailing whitespace or a different encoding, the key is base64-encoded on one side and raw bytes on the other, or the signature is hex vs. base64 encoded differently.
What's a timing attack on HMAC?
If HMAC comparison exits early on the first mismatched byte, an attacker can measure response time to guess bytes one at a time. Constant-time comparison eliminates this by always comparing all bytes.
How do I prevent replay attacks with HMAC?
Include a timestamp in the signed payload and verify that the timestamp is within an acceptable window (typically 5-15 minutes). Reject requests with a valid HMAC but an expired timestamp.