You need to verify that a message hasn't been tampered with. You've heard of HMAC and digital signatures. Both solve authenticity problems — but they're not interchangeable. Using the wrong one is a security mistake, not just a style preference.
What HMAC Actually Does
HMAC (Hash-based Message Authentication Code) combines a secret key with a hash function (typically SHA-256) to produce a fixed-length tag. The receiver recomputes the tag using the same key and compares. If they match, the message is authentic and unmodified.
The critical point: anyone who can verify an HMAC can also create one. There's no separation of concerns between signing and verifying — both require the same secret.
This makes HMAC ideal when:
- You control both endpoints (e.g., your server signs, your server verifies)
- You're authenticating webhook payloads
- You're building stateless session tokens for internal use
- Speed matters and you're doing high-volume request signing
What Digital Signatures Actually Do
Digital signatures use asymmetric cryptography. The sender signs with a private key. Anyone with the corresponding public key can verify the signature — but cannot forge one.
This separation is what enables non-repudiation: if you signed it, only you could have done so. The verifier can't produce a valid signature on your behalf.
Use digital signatures when:
- You need to prove who signed, not just that it was signed
- External parties need to verify without sharing a secret
- You're issuing JWTs with RS256/ES256 (public key verification by third parties)
- You're signing documents, software artifacts, or legal records
The Key Decision: Do Both Sides Need to Be Trusted Equally?
This is the real question. Here are common scenarios mapped to the right tool:
Use HMAC when:
- Webhook verification — Stripe, GitHub, Twilio all use HMAC-SHA256. Your server holds the secret; you verify incoming payloads.
- Internal service-to-service auth — both services are yours, both know the secret.
- Signed cookies or session tokens — your own backend signs and verifies.
- API request signing — AWS Signature v4 is HMAC-based.
Use Digital Signatures when:
- JWTs for third-party consumption — RS256 or ES256 lets any service verify your token with your public key.
- Code signing / release artifacts — you publish the public key; users verify your binary was untampered.
- Legal or audit records — you need to prove a specific private key holder signed a document.
- OAuth / OpenID Connect — identity providers sign tokens with their private key; relying parties verify with the public key from the JWKS endpoint.
The Non-Repudiation Trap
A common mistake: using HMAC for audit logs or legal records. If Alice and Bob share an HMAC secret, and you find an HMAC-signed record, you cannot prove Alice created it — Bob could have too. Either party can deny it.
Digital signatures solve this. Only the holder of the private key could have produced a valid signature. That's what non-repudiation means.
Performance Reality Check
HMAC-SHA256 is extremely fast — often 10–100x faster than RSA-2048 signing. For high-throughput systems doing millions of request verifications, this matters. ECDSA (P-256) is significantly faster than RSA and is the modern choice when you do need asymmetric signatures.
If you're signing 50,000 JWTs per second, RS256 will hurt. ES256 is a reasonable middle ground. But if non-repudiation isn't a requirement, HS256 (HMAC) is the correct and fastest choice.
If you control both ends → HMAC. It's simpler, faster, and perfectly secure for internal authentication.
If the verifier is someone else, or you need proof of origin → Digital signatures. The extra complexity of key pairs is the price of non-repudiation and public verifiability.
Don't reach for asymmetric cryptography because it "sounds more secure." HMAC with a proper
Frequently Asked Questions
Related posts
Prompt Injection: Why You Can't Fix It With a Better Prompt
Prompt injection isn't a filtering problem you can prompt your way out of. It's an architecture problem — the model can't tell your instructions from the data it's reading. Here's what actually contains it.
Jul 28, 2026 · 11 min readPhishing URLs: How Attackers Fake Domains (and How to Read Them)
Typosquatting, homograph attacks, subdomain deception, and the @ trick — learn the handful of URL tricks behind most phishing, and the one habit that beats all of them.
Jun 13, 2026 · 7 min readWhat Is CSV Injection — and How to Stop It in Your Export Feature
CSV (formula) injection turns a harmless 'export to spreadsheet' button into code execution on whoever opens the file. Here's how the attack works and how to prevent it.
Jun 13, 2026 · 7 min read