Implementing HMAC Scheme To Protect API Requests

7 minute read

In this guide you’ll learn about an important authentication scheme called HMAC - what is it, its advantages, things to consider while implementing a strong HMAC and a unique form of HMAC (invented by ASPSecurityKit team) to protect service callbacks (webhooks).


Hash-based Message Authentication Code (HMAC) is a specific type of code obtained using a cryptographic hash function, data and a secret and is used to establish the authenticity of a message. Both parties agree to use a pre-known secret for generating HMACs before communication happens. IN a multi-user scenario, the HMAC is also accompanied by an identifying key which helps the receiver to locate the secret used by the sender.


HMAC has the following key advantages:

  1. Authentication without revealing the secret – With HMAC the secret never needs to travel with the request which could otherwise be subject to MIM attack over an unsecured connection. API calls are more vulnerable to revealing the authentication credentials than revealing a password over posting a login form because the latter is always preceded by an HTTP get call (to load the webpage containing the form) and therefore server gets a chance to enforce TLS/SSL. On the other hand, a typical API call doesn't have this get/post cycle. It is usually independent and self-contained with identification data included in every request. Hence, if the server allows authentication just based on the identifying key passed in the request, it can be revealed to a man-in-middle (MIM) adversary before the server receives an insecure request and enforce SSL.
  2. Data Integrity – While computing HMAC signature we can consider such things as URL, HTTP method, timestamp, request body ETC. This gives the server the ability to verify the integrity of the request and thwart data tampering attacks including replay attacks. The signature is computed based on a common secret known to both client and server but not to the MIM adversary.

Request Components to Compute HMAC

HMAC provider in ASPSecurityKit uses following request components to compute HMAC signature:

  1. IdTokenType (lowercase - but should be exactly as specified in authorization header) – Specifies the type of the identity token being used to compute the HMAC. ASK supports multiple kinds of identity tokens (to enable various kinds of integration scenarios) like APIKey, user session etc. IdTokenType helps in determining where to look for that token record in the database so we can locate the secret and other details associated with it.
  2. IdToken (lowercase - but should be exactly as specified in authorization header) – Specifies the identity token itself (APIKey or sessionId etc.).
  3. URL (lowercase) – All components including scheme and query string.
  4. HTTP Method (uppercase) – Such as GET, POST.
  5. Timestamp (UNIX) – Total seconds elapsed since UNIX epoch start (1970-01-01 0:0:0).
  6. Message Body – Base64 MD5 hash of the request body (if there is one).
  7. Nonce – A random value (typically a GUID) to prevent replay attacks (see below).

Steps to Building the HMAC Signature and Signing the Request

  1. Combine signature data in the below format (without brackets of course):
  2. Compute an HMAC signature of this data using SHA256 algorithm with Secret as the input key.
  3. Add an Authorization header to the request using a custom scheme “HMAC” as follows (colon is required as a delimiter):
    Authorization: HMAC IdTokenType:IdToken:SignatureBase64String:Nonce:Timestamp
Authorization: ask-hmac sessionid:689c727e23c94f388a5a9e1dbf83a100:YO0C4/lTYQN9oKd+Qt8WuK6bHPDv8stN1Q+LDzJWz1M=:3b661b70a71345fc860c4489d1c0e095:1605180631

Replay Attacks

The strong data integrity check built into HMAC signature computation ensures that a snooper can't really alter (tamper with) or post a malicious request to the server without possessing the secret. However, he can still cause a replay attack which is basically re-issuing exactly the same request over and over again. The server may or may not accept the request depending on the business logic but if it does it can still cause damage to user data and privacy.

It is easy to incorporate protection against replay attacks in HMAC by introducing a random value called nonce. If every request requires a unique random value for computing the HMAC signature, no two otherwise identical requests will remain identical. This requires that the server caches the HMAC token it receives with every request and validates that the same token is not used again.

Expiring Window

On a system with high-throughput, caching HMAC token could quickly overwhelm the cache storage if not managed properly. However, if we only cache the token for a small interval – say five minutes – we no longer have to worry about it. But this requires that we reject the requests older than the caching expiration interval and the timestamp component in HMAC token helps us in determining just that. it also makes perfect sense as we do not see a need for callers to create a request but hold it from issuing right away.

System Clock Syncing Issues

When we enforced short expiry window (in ISCP and Gluco) we found some requests often failing with expired request. These were not deliberate attempts to call with old signatures. Rather, these were caused by users' system clocks not synced with the correct time or were using the wrong time zones. It's frustrating for the users and equally difficult for us (the dev team) to reach out to the users to help them fix their system clock.

To solve this problem, we thought of a different automated alternative. What if clients get the current time from the server itself? We implemented a simple endpoint – GetUTCTime – and marked it with [AllowAnonymous] so there's no security pipeline execution. The endpoint executes within 1 MS and solves the system clock issue once and for all.

Service HMAC (SHMAC) Token

SHMAC is a unique lighter and flexible type of HMAC token supported by ASPSecurityKit for securing callbacks (webhooks and others) from third-party services (TPS), which includes but not limited to digital signing (such as DocuSign), payment gateways etc., if the service supports specifying callback URL dynamically.

Upon receiving a callback from a TPS, you likely need to perform a sensitive operation (of completing the signature or updating payment status, for example). This would require loading the security context with appropriate privileges to perform the operation. You may think that by ensuring execution of the callback over a secure connection you've eliminated any potential threat. But what if the TPS gets compromised? Your callback suddenly becomes open for the attacker to issue damaging requests. The more open-ended (in terms of accepting data values) the callback is, the greater damage it can cause to your system.

SHMAC helps you protect against such callback attacks and limits the potential scale of the damage to the minimum. To use SHMAC, you dynamically generate a callback URL with SHMAC token embedded into it. It has the following differences from regular HMAC token:

  1. You can specify exactly which query params will be used to compute the signature upon callback for each endpoint. ServiceHMAC provider will ignore other params present in the URL. Often callbacks are invoked with additional params (appended to the query string) by TPS depending on the result of the processing. Since the result is not known in advance you would not want to consider such params while computing the HMAC signature.

    [AcceptServiceHmacToken(ApplyTo.Get, JustTheseQueryParams = new[] { "itemId" })]
    public class UpdatePaymentStatusRequest
  2. Often TPS may take hours or days before invoking the callback (in case of DocuSign it will invoke after the user signs the document, for example). Certainly, such an HMAC token can't have a small expiry window. SHMAC allows you to configure this expiry window on a per-endpoint basis.

    [AcceptServiceHmacToken(ApplyTo.Get, JustTheseQueryParams = new[] { "itemId" },
        ValidForDays = 5)]
    public class ESignedRequest
  3. Lastly, both of the above configurations are also used as input data to the signature computation and also appended to the HMAC token. This ensures that the generated SHMAC is self-contained and you are free to make changes to the declaration for future callbacks without worrying that such a change will break existing callbacks.



HMAC is one of the most secure method to authenticate API calls. It has unique properties to provide protection against MIM attacks like replay and request tampering. ASPSecurityKit provides a complete end-to-end implementation of providers for both server and JS clients to integrate HMAC in your API service.

Additionally, ASK provides a unique form of HMAC, called SHMAC, which helps you secure automated webhooks and callbacks from other services using similar protection provided by HMAC but with the flexibility of choosing the expiry interval and specific URL parameters for validating the signature, both configurable per-endpoint basis.

Black Hills Information Security (BHIS) performed a week-long web application and API penetration test of ISCP (its security based on ASPSecurityKit) in January 2019. In its assessment report BHIS noted:

BHIS would like to commend IRA Services Inc. on its implementation of the authorization header. The dynamic nature of this header helps to secure the application by preventing replay attacks and request tampering.

Don't Miss Out!

Be the first to get notified when the new quality content related to web app security like the one you're reading is posted.

Need help?

Looking for expert security guidance, security review of your source code or penetration testing of your application, or part-time/full-time assistance in implementation of the complete web application and/or its security subsystem?

Just send an email to [email protected] with the details or call us on +16282502591.

Related tags

HMAC , SHMAC , API , Replay-Attack , Request-Tampering , Data-Integrity , BHIS