DEV Community

Collabier
Collabier

Posted on

HMAC Explained: What It Is and Why APIs Use It

If you've ever worked with payment APIs, webhooks, cloud services, or third-party integrations, you've probably seen something that looks like:

```text id="3n8x5k"
X-Signature: 9d7f3a...




At first glance, it just looks like another random hash.

But sometimes that signature is actually an **HMAC**.

HMAC is one of those security concepts that sounds more complicated than it really is. Once you understand what it's doing, you'll start noticing it everywhere in API authentication and request verification.

## What is HMAC?

HMAC stands for **Hash-based Message Authentication Code**.

The basic idea is pretty straightforward.

You have:

1. A message
2. A secret key
3. A cryptographic hash function

The HMAC algorithm combines the message and secret key to produce a signature.

Conceptually:



```text id="1x6u8e"
HMAC(secret_key, message) → signature
Enter fullscreen mode Exit fullscreen mode

For example, an API might have a shared secret:

```text id="g4s6hf"
my-super-secret-key




and a request payload:



```json
{
  "amount": 100,
  "currency": "USD"
}
Enter fullscreen mode Exit fullscreen mode

The sender generates an HMAC signature using the secret key.

The receiving server already knows the same secret key, so it can calculate the signature again.

If the signatures match, the server has a reasonable way to verify that the message was generated by someone who knows the secret.

That's the important part.

Hashing isn't the same as HMAC

This is where things can get confusing.

A normal cryptographic hash might look like:

```text id="xk4h6z"
SHA-256(message)




There's no secret involved.

Anyone with the message can calculate the same hash.

HMAC is different:



```text id="0p6t5c"
HMAC-SHA256(secret, message)
Enter fullscreen mode Exit fullscreen mode

The secret key is part of the authentication process.

So if someone modifies the message but doesn't know the secret key, they shouldn't be able to generate a valid HMAC for the modified message.

This is why HMAC is useful for verifying the integrity and authenticity of data.

A common API example

Imagine you're receiving a webhook from a payment provider.

The provider sends:

{
  "event": "payment.completed",
  "id": "12345",
  "amount": 500
}
Enter fullscreen mode Exit fullscreen mode

Along with something like:

```text id="p0q4a6"
X-Signature: abc123...




Your server receives the request and uses your shared secret to calculate its own HMAC signature.

Conceptually:



```text id="o1h2ly"
expected = HMAC-SHA256(secret, request_body)
Enter fullscreen mode Exit fullscreen mode

Then it compares the generated signature with the signature sent by the provider.

If they match, the request passes the signature check.

If they don't, something is wrong.

Maybe the request was modified.

Maybe the wrong secret was used.

Maybe the payload was interpreted differently.

Or maybe someone is trying to send a fake webhook.

The exact bytes matter

This is one of those details that can cause an annoying debugging session.

HMAC operates on the actual message bytes.

That means these two JSON strings may represent the same data to you:

{"amount":100,"currency":"USD"}
Enter fullscreen mode Exit fullscreen mode

and:

{
  "amount": 100,
  "currency": "USD"
}
Enter fullscreen mode Exit fullscreen mode

But their raw byte representations are different.

If one side calculates the HMAC from one representation and the other side calculates it from another, the signatures won't match.

That's why webhook implementations often tell you to calculate the signature against the raw request body, rather than parsing the JSON first and then serializing it again.

Tiny implementation detail.

Huge debugging headache.

Which hash algorithms can HMAC use?

HMAC isn't itself a hash function.

It's a construction that can be used with different hash functions.

The tool I built supports:

  • HMAC-SHA-256
  • HMAC-SHA-384
  • HMAC-SHA-512
  • HMAC-SHA-1

SHA-256 is a common choice for modern applications.

SHA-384 and SHA-512 are also available when required by a particular protocol or integration.

SHA-1 is included mainly for compatibility with older systems.

For new security-sensitive designs, you generally shouldn't choose SHA-1 simply because it's available.

If an existing API explicitly requires it, though, you'll occasionally need to generate an HMAC-SHA-1 signature.

Legacy software has a remarkable talent for refusing to retire.

I built an HMAC generator

I made a small HMAC Keyed-Hash Signature Generator for quickly generating and testing HMAC signatures.

👉 https://omnikite.vercel.app/tools/security/hmac-generator

You can enter your message, provide the secret key, select the hashing algorithm, and generate the resulting HMAC signature.

It's useful when you're:

  • Debugging an API integration
  • Testing webhook signatures
  • Checking an authentication implementation
  • Comparing signatures between two systems
  • Learning how HMAC works
  • Troubleshooting a request-signing issue

Sometimes you don't need an entire cryptography library setup just to answer:

"Why the hell don't these two signatures match?"

A small tool is enough.

Everything happens in the browser

Since HMAC involves secret keys, I didn't want the generator to require sending your input to a backend.

The tool runs entirely on the client.

Your message and key stay in the browser, with zero data egress.

Of course, you should still use common sense.

Don't paste production credentials into random tools just because the page says "private."

For real secrets, use tooling and environments you trust.

HMAC doesn't encrypt anything

Another important distinction:

HMAC does not encrypt your message.

If you calculate:

```text id="5gk7p2"
HMAC-SHA256(secret, "hello")




the result doesn't allow someone to decrypt `"hello"`.

HMAC is primarily about **authentication and integrity**, not confidentiality.

If you need to keep the message secret, you need encryption.

If you need to verify that the message hasn't been tampered with and that the sender knows the shared secret, HMAC can be a good fit.

Different problem.

Different tool.

## HMAC in the real world

You'll find HMAC-style request signing in many places.

For example:

**Webhooks**

A provider signs the payload and your server verifies the signature.

**API authentication**

A client can sign requests using a shared secret.

**Cloud APIs**

Some cloud services use request-signing mechanisms built around HMAC.

**File or message integrity**

A system can use HMAC to detect unauthorized modification when the communicating parties share a secret.

The exact protocol varies, but the fundamental idea remains the same:

> Both sides know the secret. Only someone with that secret should be able to produce a valid signature.

## Try it yourself

If you're currently debugging an API signature or simply want to understand how HMAC works, you can try the generator here:

👉 **HMAC Keyed-Hash Signature Generator**
https://omnikite.vercel.app/tools/security/hmac-generator

It supports SHA-256, SHA-384, SHA-512, and SHA-1 HMAC signatures and runs entirely client-side.

Sometimes understanding cryptography doesn't require reading a 400-page specification.

Sometimes you just need to enter a message, enter a secret, press a button, and finally figure out why the API keeps saying:

**"Invalid signature."**
Enter fullscreen mode Exit fullscreen mode

Top comments (0)