HMAC vs Digital Signatures
In-Depth Technical Comparison & Architecture Guide
Both HMAC and digital signatures let a recipient verify a message wasn't tampered with, but they answer a different second question: HMAC only proves the message came from someone who holds a shared secret, while a digital signature proves it came from the one specific party holding a private key — and only the second property, non-repudiation, actually holds up if the sender later denies sending it.
Quick Reference Matrix
| Feature | HMAC | Digital Signatures |
|---|---|---|
| Key Model | Symmetric — one shared secret | Asymmetric — private key signs, public key verifies |
| Governing Standard | RFC 2104, FIPS 198-1 | RFC 8017 (RSA), FIPS 186 (ECDSA), RFC 8032 (EdDSA) |
| Execution Speed | Very fast (microseconds) | Significantly slower (asymmetric math) |
| Non-repudiation | No — either party could have produced it | Yes — only the private key holder could sign |
| Key Distribution Requirement | Secret must reach both parties securely in advance | Public key can be freely published |
| Common JWT Algorithm | HS256 | RS256, ES256 |
Technology Overview
HMAC (Hash-based Message Authentication Code), formalized in RFC 2104 and later reaffirmed as a NIST standard in FIPS 198-1, combines a cryptographic hash function (commonly SHA-256) with a secret key shared between exactly two parties. Its construction is specific and standardized: HMAC(K, m) = H((K ⊕ opad) || H((K ⊕ ipad) || m)) — the key is XORed with two different padding constants and mixed into two nested hash operations, a design specifically chosen to be secure even when built on a hash function that isn't itself perfectly collision-resistant.
Digital signatures (RSA signatures per RFC 8017/PKCS#1, ECDSA per FIPS 186, or EdDSA per RFC 8032) instead use an asymmetric key pair: the sender signs a message's hash with their private key, and anyone holding the corresponding public key can verify the signature — without ever needing access to the private key itself.
The practical consequence of this structural difference is the whole reason to choose one over the other: because HMAC's secret is shared, either party could have produced a given HMAC, so a receiver can't prove to a third party which side actually sent a message — there's no non-repudiation. A digital signature's private key never leaves the signer's possession, so a valid signature is specific evidence that only that key holder could have produced it, which is exactly what non-repudiation requires.
The Key-Sharing Problem and Non-Repudiation
HMAC requires both the sender and the verifier to already possess the identical secret key before any communication happens — a key-distribution problem that has to be solved separately (and securely) before HMAC itself can be used at all. Once both parties have the key, either one can produce a valid HMAC for any message, which means an HMAC alone can't settle a dispute about who actually authored a specific message; both parties are equally capable of having produced it.
Digital signatures sidestep the key-distribution problem for the signing side entirely: the public key can be shared freely and published anywhere, since it only allows verification, not signing. Because only the private key holder can produce a valid signature, a verified signature is meaningful evidence of authorship in a way a matching HMAC never can be — this is precisely why signatures, not HMACs, are used for anything requiring accountability after the fact (contracts, code publishing, financial transactions).
Performance: Why HMAC Is Dramatically Faster
HMAC is built entirely from symmetric-key primitives (a hash function), which are computationally cheap — modern hardware computes an HMAC-SHA256 over a typical payload in microseconds, and the operation scales linearly and predictably with message size.
Digital signature operations rely on asymmetric-key mathematics (modular exponentiation for RSA, elliptic curve point operations for ECDSA/EdDSA), which are inherently far more computationally expensive than a hash operation — commonly one to three orders of magnitude slower per operation than HMAC, depending on the specific algorithm and key size. This is exactly why systems requiring extremely high message-authentication throughput (internal microservice-to-microservice traffic, for example) default to HMAC wherever the parties already share a trust relationship that makes non-repudiation unnecessary.
Real-World Usage: JWT's HS256 vs RS256/ES256 Choice
JSON Web Tokens are a concrete, everyday example of this exact tradeoff in action: a JWT can be signed with HS256 (HMAC-SHA256, a shared-secret construction) or with RS256/ES256 (RSA or ECDSA digital signatures). HS256 is simpler and faster, and is a reasonable choice when a single service both issues and verifies its own tokens — the 'shared secret' problem doesn't really apply, since only one party ever needs the key.
RS256/ES256 becomes the right choice the moment more than one party needs to verify tokens without being trusted to issue them — a common pattern in microservice architectures where an authentication service signs tokens with a private key, and many downstream services verify them using only the corresponding public key, never needing (or being trusted with) signing capability themselves. See the Authentication & Tokens hub's JWT tooling for generating and inspecting tokens using either scheme.
HMAC Advantages & Disadvantages
Advantages / Pros
- Extremely fast — negligible computational overhead per message.
- Simple, well-standardized construction (RFC 2104 / FIPS 198-1).
- Ideal when a single trusted party both issues and verifies.
Disadvantages / Cons
- No non-repudiation — can't prove which party actually sent a message.
- Requires securely distributing a shared secret before any communication.
- A leaked key compromises both the ability to forge and to verify messages.
Digital Signatures Advantages & Disadvantages
Advantages / Pros
- Provides genuine non-repudiation — a signature is specific evidence of the signer's identity.
- Public key can be distributed freely with no confidentiality requirement.
- Appropriate for multi-party verification without shared trust in a single secret.
Disadvantages / Cons
- Meaningfully slower than HMAC due to asymmetric-key mathematics.
- Key pair generation and management is more involved than a single shared secret.
- Larger signature sizes than an HMAC digest, in most common algorithm choices.
Real-World Use Cases
HMAC
Internal microservice-to-microservice authentication
Where all parties are within the same trust boundary and non-repudiation between them isn't a real requirement.
Webhook payload verification
Confirming a webhook payload actually came from the expected sender, who shares a secret established at webhook registration time.
Single-issuer JWTs (HS256)
A service that both issues and verifies its own tokens, where the 'shared secret' is only ever known to that one service.
Digital Signatures
Multi-service JWT verification (RS256/ES256)
An identity provider signs tokens; many independent downstream services verify them using only the public key, never holding signing capability.
Code signing
Verifying that a published software artifact genuinely came from its claimed publisher, with accountability that holds up after the fact.
Financial and legal transaction records
Contexts where non-repudiation is a hard requirement, not just a nice-to-have.
Developer Recommendation
Use HMAC when a single trusted party (or a small, tightly-controlled set of parties who already fully trust each other) both produces and verifies the authentication code, and raw performance matters — internal service-to-service calls, single-issuer JWTs, and webhook signatures are all good fits.
Use digital signatures the moment you need non-repudiation (proof of who specifically produced a message) or need to let many parties verify authenticity without being trusted to also produce it — multi-service JWT verification, code signing, and any scenario with real accountability requirements after the fact.
If you're specifically choosing a JWT signing algorithm: HS256 for a single service issuing and verifying its own tokens, RS256 or ES256 the moment more than one independently-operated service needs to verify tokens it didn't issue.
Frequently Asked Questions
- Does HMAC provide non-repudiation?
- No — because both parties hold the identical shared secret, either one could have produced a given HMAC. There's no way to prove after the fact which specific party actually sent the message, which is exactly what non-repudiation requires and digital signatures provide instead.
- Why is HMAC so much faster than a digital signature?
- HMAC is built entirely from symmetric-key hash operations, which are computationally cheap. Digital signatures rely on asymmetric-key mathematics (modular exponentiation or elliptic curve operations), which are inherently far more expensive per operation — commonly one to three orders of magnitude slower than HMAC.
- Should I use HS256 or RS256 for my JWTs?
- HS256 (HMAC) if a single service both issues and verifies its own tokens. RS256 or ES256 (digital signatures) the moment multiple independently-operated services need to verify tokens without being trusted to issue them — a very common pattern in microservice architectures.
- Is HMAC less secure than a digital signature?
- Not in terms of raw cryptographic strength for its actual purpose (proving message integrity and shared-secret authenticity) — it's a different security property being provided. HMAC is not weaker at what it does; it simply doesn't (and structurally cannot) provide non-repudiation the way a signature does.
- What happens if an HMAC shared secret leaks?
- Anyone with the leaked secret can both forge valid messages and verify others' messages — the compromise is total for that key, since HMAC makes no distinction between the ability to sign and the ability to verify.
- Can I convert a system from HMAC to digital signatures later?
- Yes, but it typically requires re-architecting how verification works across every party involved, since the trust model fundamentally changes from 'shares a secret' to 'trusts a public key' — plan for a coordinated migration rather than a drop-in swap.
Part of the Hashing & Integrity Developer Hub
This comparison is part of our Hashing & Integrity topic guide, covering related tools, standards, and decision guidance.
Related Comparisons
Other technology decisions in the same topic area as Hashing & Integrity:
SHA256 vs SHA512
Cryptographic hash functions are designed to ingest arbitrary binary inputs and return a fixed-size, deterministic byte sequence called a digest. These functions must be one-way (infeasible to reverse-engineer) and collision-resistant (highly unlikely that two distinct inputs produce the same hash). In modern cryptography, the SHA-2 (Secure Hash Algorithm 2) family is the default choice for data integrity, SSL/TLS certificates, and blockchain networks. Within this family, SHA-256 and SHA-512 are the two most prominent algorithms. Surprisingly, their differences extend beyond digest length to internal block sizes, math architectures, and hardware parsing performance. This guide compares SHA-256 and SHA-512 in detail.
Bcrypt vs Scrypt
Bcrypt and Scrypt both slow down password verification deliberately, but they do it in fundamentally different ways: Bcrypt spends CPU cycles alone, while Scrypt deliberately consumes large amounts of memory alongside CPU time. That single architectural difference — memory-hardness — is the whole reason Scrypt exists, and it's the lens this comparison uses throughout.
MD5 vs SHA1 vs SHA256
MD5 and SHA-1 are both cryptographically broken — not theoretically weak, but practically broken, with real, demonstrated attacks — while SHA-256 remains secure with no known practical attack. This comparison is less about a tradeoff between three roughly-equivalent options and more about understanding exactly why two of them were retired and what, if anything, they're still safe to use for.
Argon2 vs Scrypt
Argon2 and Scrypt are both memory-hard — the defining property that separates them from Bcrypt (see Bcrypt vs Scrypt) — but Argon2 refines the idea with a hybrid access pattern specifically designed to resist both GPU cracking and side-channel timing attacks simultaneously, something plain Scrypt's single access pattern can't do at once.
Launch Interactive Developer Tools
Put these concepts into practice. Test, format, serialize, or analyze your inputs locally with these secure, browser-only utilities: