MultiConnect

HMAC SHA256 API Authentication Sign Requests Securely

HMAC SHA256 API authentication helps developers verify that API requests were created by someone who possesses a shared secret and that the signed request data has not been altered. It combines a secret key with a cryptographic hash function to generate a message authentication code that the receiving server can verify.

Whether you are building a payment integration, connecting backend services, or securing a custom application, implementing request signing can add an important layer of protection. This practical guide explains how HMAC-SHA256 works, how to generate and verify signatures, and which security practices help prevent common authentication mistakes.

HMAC SHA256 API Authentication

What Is HMAC SHA256 API Authentication?

HMAC-SHA256 uses a secret key and the SHA-256 hash algorithm to generate a message authentication code. The client signs agreed-upon request data, and the server independently calculates the expected signature using the same secret key.

Unlike a simple API key sent with a request, a signed request can help the server detect changes to the signed content. However, HMAC does not encrypt request data, establish identity by itself, or prevent replay attacks without additional protections.

Shared Secret Key

A private key shared securely between the client and server is used to generate and verify request signatures.

Canonical Request Data

Both sides construct the same message from agreed-upon fields, such as the HTTP method, request path, timestamp, and body digest.

Signature Generation

The client computes an HMAC-SHA256 value from the canonical message and encodes the resulting bytes, commonly as hexadecimal or Base64.

Server-Side Verification

The server recomputes the signature, compares it safely, and rejects requests that fail authentication or timestamp validation.

HMAC-SHA256 API Request Signing Example

To implement HMAC SHA256 API authentication, the client and server must agree on the exact message format, character encoding, signature encoding, and secret key. Even a small difference in whitespace, URL path, timestamp, or request body can produce a different signature. For this practical example, assume a client sends a POST request to /api/orders. The signed message contains the HTTP method, request path, Unix timestamp, and SHA-256 digest of the request body. Both parties must construct these fields identically before generating or verifying the signature.

In C#, the HMACSHA256 class from System.Security.Cryptography provides the cryptographic operation needed to create the signature. The official Microsoft HMACSHA256 documentation explains the API and its use for message authentication.

HMAC-SHA256 API Request Signing
C#
1using System.Security.Cryptography;2using System.Text;34public static class ApiRequestSigner5{6    public static string Sign(string secret, string message)7    {8        byte[] key = Encoding.UTF8.GetBytes(secret);9        byte[] data = Encoding.UTF8.GetBytes(message);1011        using var hmac = new HMACSHA256(key);12        byte[] signature = hmac.ComputeHash(data);1314        return Convert.ToHexString(signature).ToLowerInvariant();15    }16}1718// Build the canonical message and sign it19string secret = Environment.GetEnvironmentVariable("API_HMAC_SECRET")20    ?? throw new InvalidOperationException("Missing HMAC secret.");2122string method = "POST";23string path = "/api/orders";24string timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();25string body = """{"productId":123,"quantity":2}""";2627byte[] bodyBytes = Encoding.UTF8.GetBytes(body);28string bodyHash = Convert.ToHexString(29    SHA256.HashData(bodyBytes)).ToLowerInvariant();3031string message = $"{method}\n{path}\n{timestamp}\n{bodyHash}";3233string signature = ApiRequestSigner.Sign(secret, message);
This example creates a request signature from the HTTP method, path, timestamp, and SHA-256 hash of the request body.

Verify HMAC Signatures Securely

Implementing HMAC SHA256 API authentication requires more than generating a signature. Your API must validate every signed request, reject expired timestamps, and compare signatures securely before allowing protected operations.

Recalculate the signature

Rebuild the canonical message from the received request and calculate a new HMAC using the secret stored on the server.

Compare signatures safely

Decode and validate the supplied signature, then use CryptographicOperations.FixedTimeEquals to compare equal-length signature byte arrays.

Prevent replay attacks

Enforce a short timestamp validity window and reject reused request identifiers when your protocol supports unique nonces or idempotency keys.

Six Best Practices for HMAC-SHA256 API Authentication

Protect the secret key

Store secrets in a secure configuration provider or secrets manager. Never expose private signing keys in frontend JavaScript, public repositories, URLs, or application logs.

Use HTTPS everywhere

HTTPS protects request data and credentials during transmission. HMAC verifies message authenticity but does not encrypt the payload or replace transport security.

Define canonicalization rules

Specify the HTTP method, normalized path, query parameters, timestamp, and body digest precisely. Ensure clients and servers construct identical messages consistently.

Validate timestamps and nonces

Reject requests outside an acceptable time window. Track unique request identifiers where possible to prevent attackers from successfully replaying captured signed requests.

Rotate keys periodically

Support controlled key rotation, identify which client owns each key, and revoke compromised credentials promptly without exposing replacement secrets.

Test negative scenarios

Verify that modified bodies, incorrect signatures, expired timestamps, missing headers, and duplicate nonces are rejected consistently before sensitive operations execute.

Frequently Asked Questions

Is HMAC-SHA256 more secure than an API key?

They serve different purposes. An API key identifies a client or credential, while HMAC can authenticate signed request data. Combining them can be useful, provided secrets are protected and requests are validated correctly.

Can I implement HMAC-SHA256 in ASP.NET Core?

Yes. ASP.NET Core applications can use HMACSHA256 from System.Security.Cryptography to generate signatures and verify requests using a shared secret.

Does HMAC-SHA256 prevent replay attacks?

No. A valid signed request could be captured and resent. Use signed timestamps, a short validity window, and server-side nonce or request-ID tracking to reduce replay risk.

Scroll to Top