Every time a server checks whether an API request, a webhook payload, or a firmware update was tampered with in transit, it leans on one of two workhorses: HMAC or CMAC. Both are message authentication codes. Both stop an attacker from silently altering data. But they get there through completely different math, and picking the wrong one can cost you throughput, hardware budget, or compliance headaches down the line.
HMAC wraps a keyed secret around a hash function like SHA-256. CMAC runs a block cipher, almost always AES, through a modified chaining construction. JWT’s HS256 header is HMAC. The tap you use to unlock a hotel door with Bluetooth Low Energy is probably CMAC. This comparison breaks down the construction, the benchmarks, the standards, and the real deployments so you can pick the right primitive for the system you’re actually building in 2026.
The confusion between the two is understandable. Both take a secret key and a message, both output a fixed-size tag, and both exist to answer the same question: did this data arrive unmodified from someone who holds the key? But the engineering trade-offs sitting underneath that shared goal are large enough to shape hardware choices, library selection, and even which compliance audits a system can pass. A payment terminal vendor picking HMAC because “it’s more popular” can fail an EMV certification. A backend team picking CMAC because a blog post called it “faster” can end up vetting an unmaintained third-party Go package instead of shipping features. Neither mistake is rare.
What Is HMAC and How Does It Work
HMAC stands for Hash-based Message Authentication Code. It was defined in RFC 2104 back in February 1997 and later formalized by NIST in FIPS 198-1. As of 2025, NIST proposed retiring FIPS 198-1 and folding its content into a new document, NIST SP 800-224, so anyone citing “the HMAC standard” in 2026 should point to both the original RFC and the current NIST publication status.
The construction itself is a nested hash. For a hash function H with block size B, HMAC computes H((K’ XOR opad) || H((K’ XOR ipad) || M)), where K’ is the key padded to the hash’s block size, ipad and opad are fixed constant bytes, and M is the message. That double-hashing is the entire point: it’s what stops the classic length-extension attack that plagues naive constructions like SHA256(key + message). A raw hash of a secret concatenated with a message can, under certain conditions, let an attacker append data and compute a valid new hash without ever seeing the key. HMAC’s nested structure closes that door entirely.
Because HMAC is hash-agnostic, you’ll see it named after whatever hash sits underneath: HMAC-SHA256 produces a 256-bit tag, HMAC-SHA384 produces 384 bits, and HMAC-SHA512 produces 512 bits. Key length is flexible too. In practice, most engineering teams settle on a key that matches the underlying hash’s output size and never touch it again.
What Is CMAC and How Does It Work
CMAC stands for Cipher-based Message Authentication Code. NIST published its specification in SP 800-38B in May 2005, and it’s built as a fix for the older CBC-MAC pattern, which turns out to be insecure for variable-length messages unless you patch it carefully. CMAC is that patch, standardized.
Here’s the mechanical version. CMAC encrypts an all-zero block under the chosen AES key to get a value L, then derives two subkeys, K1 and K2, through finite-field doubling of L. The message gets split into 128-bit blocks (AES’s block size). If the final block is a complete 128 bits, K1 gets XORed into it before the last encryption round. If the final block is short, it gets padded with a 1 followed by zeros, and K2 gets XORed in instead. Every block before the last runs through standard CBC chaining. The output of the final AES encryption, sometimes truncated, is the tag.
That K1/K2 subkey trick is what separates CMAC from plain, broken CBC-MAC. Skip it, and an attacker can forge tags for messages that are simple prefix-extensions of ones they’ve already seen signed. Modern deployments use AES-CMAC almost exclusively; the older 3-key Triple DES variant is legacy and shouldn’t appear in new designs. Because AES has a 128-bit block, AES-CMAC’s full tag tops out at 128 bits regardless of whether you’re running AES-128, AES-192, or AES-256 underneath. The larger keys buy you stronger key security, not a bigger tag.
It’s worth pausing on why the industry needed CMAC at all when AES-based authentication existed for decades under CBC-MAC. The problem with plain CBC-MAC is that it’s only safe when every message being authenticated is a fixed, known length. The moment you allow variable-length messages, an attacker who has seen a valid tag for a short message can often compute a valid tag for a longer, attacker-chosen message without ever holding the key, simply by exploiting how CBC chaining processes the final block. CMAC’s entire design, the K1/K2 subkeys and the split treatment of complete versus incomplete final blocks, exists to close that one specific gap while keeping everything else about CBC-MAC’s simplicity and hardware-friendliness intact.
HMAC vs CMAC: Full Technical Specification Table
| Property | HMAC | CMAC |
|---|---|---|
| Underlying primitive | Cryptographic hash function (SHA-2, SHA-3) | Block cipher, virtually always AES |
| Governing standard | RFC 2104 (1997), FIPS 198-1 (2008), migrating to SP 800-224 | NIST SP 800-38B (2005) |
| Typical variant | HMAC-SHA256 | AES-CMAC (AES-128, 192, or 256) |
| Full tag length | Matches hash output: 256, 384, or 512 bits | Fixed at 128 bits (AES block size) |
| Key length | Variable, commonly matched to hash output | 128, 192, or 256 bits (AES key sizes) |
| Subkey derivation | None required | K1 and K2 derived via finite-field doubling |
| Length-extension risk | Not vulnerable, by design of the nested construction | Not applicable; different attack surface entirely |
| Variable-length message safety | Safe when correctly implemented | Safe only when the CMAC final-block rules are followed exactly |
| Best hardware fit | CPUs with SHA extensions (SHA-NI) | CPUs or chips with AES acceleration (AES-NI) |
| Ecosystem breadth | Near-universal across languages and libraries | Common in standards libraries, less consistent in general-purpose language APIs |
| NIST-approved status in 2026 | Yes, one of three approved general-purpose MAC algorithms | Yes, one of three approved general-purpose MAC algorithms |
| Typical deployment environment | Web APIs, cloud signing, key derivation | Embedded, wireless, payment, automotive hardware |
Notice the third entry from NIST: HMAC and CMAC aren’t the only game in town. NIST also recognizes KMAC, a Keccak/SHA-3-based MAC, as an approved general-purpose option, though it sees far less real-world adoption outside of blockchain and SHA-3-heavy toolchains.
Performance Benchmarks: HMAC-SHA256 vs AES-CMAC
Raw speed comparisons between HMAC and CMAC are messier than most vendor marketing suggests, because the result flips depending on whether your CPU accelerates AES, SHA, both, or neither. Three data points illustrate the range you’ll actually encounter in production.
One cross-algorithm benchmark set measured HMAC-SHA256 signing at 218 MB/s and verification at 97 MB/s, against CMAC-AES-128 at 112 MB/s signing and 67 MB/s verification on the same test rig, roughly a 2x gap in HMAC’s favor. A separate cryptography library benchmark reported HMAC-SHA256 running between 800 and 1,500 MB/s once SHA hardware extensions kick in, which shows how much the number swings once acceleration is on the table. Meanwhile, general AES-NI benchmarking on modern x86 chips consistently shows AES throughput in the multiple-GB/s range, meaning that on a system where SHA extensions aren’t present but AES-NI is, AES-CMAC can pull ahead of a software-only HMAC-SHA256 implementation.
The honest takeaway: don’t trust a single number from a blog post, including this one, without checking which instruction sets were active during the test. The variables that actually decide the winner on your hardware are message size, whether you’re doing one-shot or streaming hashing, and whether your specific CPU generation ships SHA-NI, AES-NI, both, or neither.
Message size matters more than most benchmarks let on. For short payloads, like a 200-byte webhook body or a small CAN frame, fixed overhead from key setup, function calls, and padding logic can dominate the total time, which flattens the gap between HMAC and CMAC regardless of which raw algorithm is theoretically faster. For large payloads, like a multi-megabyte file upload signed before storage, the underlying per-byte throughput of the hash or cipher takes over, and that’s where SHA-NI versus AES-NI availability actually decides the winner. If your workload is dominated by small, frequent messages, don’t over-optimize for a per-byte throughput number that will never fully materialize in your traffic pattern.
| Benchmark source | HMAC-SHA256 | AES-CMAC-128 | Conditions |
|---|---|---|---|
| Algorithm performance benchmark set | 218 MB/s sign, 97 MB/s verify | 112 MB/s sign, 67 MB/s verify | Single test rig, one-shot API |
| Cryptography library documentation | 800-1,500 MB/s | Not directly reported | SHA-NI hardware acceleration active |
| General AES-NI throughput class | Not applicable | Multiple GB/s class | AES-NI active, large block sizes |
Hardware Acceleration: Why AES-NI and SHA-NI Change the Answer
Intel and AMD have shipped SHA Extensions on mainstream x86 chips for several generations now, and ARMv8’s Cryptography Extensions bundle both AES and SHA acceleration on most modern mobile and server cores. When both instruction sets are present, which is the common case on recent AWS Graviton, Apple Silicon, and current-generation Intel and AMD server parts, the HMAC-versus-CMAC throughput gap mostly closes and the decision reverts to ecosystem and protocol fit rather than raw speed.
Where the hardware story still matters is at the edge. A lot of embedded microcontrollers, smart cards, and IoT radios ship a dedicated AES coprocessor and nothing for SHA at all, because AES is already required for encrypting the payload. On that class of device, computing CMAC is close to free since the same silicon block that encrypts your data can also generate the tag, while a software SHA-256 implementation would burn cycles and battery the chip wasn’t designed to spend. That single fact, more than any raw MB/s number, explains why CMAC dominates in constrained hardware while HMAC dominates in general-purpose software.
Security Properties: Length Extension, Birthday Bounds, and Truncation
Neither algorithm has a publicly disclosed cryptanalytic break as of September 2026. Both remain on NIST’s approved list. But “no break” doesn’t mean “no way to get it wrong,” and the failure modes for each are different enough to matter.
HMAC’s main historical concern, length extension, is specifically a weakness of naive raw-hash constructions like SHA256(key || message), not of HMAC itself. HMAC’s nested inner and outer hash calls were designed around exactly that problem, and it doesn’t apply to a correctly implemented HMAC. What does still bite teams in practice: comparing tags with a non-constant-time equality check, which opens a timing side channel, accepting truncated tags without validating the truncation length, and algorithm-confusion bugs where a server accepts a tag computed with a different hash than intended.
CMAC’s risk surface centers on the subkey derivation and final-block handling. Reuse a plain CBC-MAC implementation without CMAC’s K1/K2 treatment and padding rules, and you reopen the exact prefix-forgery weakness CMAC was built to close. This is an implementation-discipline problem more than a mathematical one, but it’s a real source of production bugs, especially in embedded codebases that hand-roll their own crypto instead of using a validated library.
Both algorithms are subject to birthday-bound reasoning: for an n-bit tag, generic forgery risk scales roughly with the number of attempts divided by 2^n. That’s why NIST requires an explicit security analysis before a protocol truncates a tag, and why the acceptable minimum truncation length is application-specific rather than a single fixed number. Automotive and payment protocols often use compact truncated tags because bandwidth is tight, and they compensate with strict freshness counters, replay protection, and rate limiting rather than relying on tag length alone.
No CVE database search turned up a 2025-2026 cryptanalytic break attributable to either core construction. The vulnerabilities that do show up in the wild are implementation bugs: non-constant-time comparisons, incorrect padding, key reuse across incompatible protocol domains, and verification logic that fails open instead of closed.
HMAC, CMAC, and the Wider MAC Family: KMAC, GMAC, and Poly1305
HMAC and CMAC don’t cover the entire MAC landscape, and it’s worth knowing the neighbors so you don’t reach for HMAC or CMAC when a purpose-built alternative already fits your protocol better.
KMAC is NIST’s third approved general-purpose MAC, built on the Keccak sponge construction that underlies SHA-3. It behaves like a hash-based MAC in the spirit of HMAC, but it’s native to the SHA-3 family rather than bolted onto SHA-2 through HMAC’s nested construction. KMAC sees real use in newer protocol designs and in blockchain-adjacent tooling that already standardized on Keccak, but it hasn’t displaced HMAC in mainstream web infrastructure, largely because SHA-2 hardware acceleration is far more widely deployed than SHA-3 acceleration.
GMAC is the authentication-only mode extracted from AES-GCM, the authenticated encryption scheme that secures most TLS 1.3 connections today. If your system already runs AES-GCM for encryption, GMAC lets you authenticate additional data without encrypting it, using the same key schedule and the same AES-NI acceleration path. It’s conceptually closer to CMAC than to HMAC since it’s block-cipher based, but its GHASH-based internals and nonce-handling rules are different enough that it deserves its own evaluation rather than being lumped in as “just another CMAC.” Readers comparing authenticated encryption modes directly may find our AES-GCM vs AES-CBC and AES-GCM vs AES-GCM-SIV breakdowns useful here.
Poly1305 is the authenticator half of ChaCha20-Poly1305, the AEAD cipher suite that competes directly with AES-GCM in modern TLS deployments and is often preferred on hardware without AES-NI, like older mobile chips. It’s neither hash-based nor block-cipher based in the traditional sense; it’s a polynomial evaluation MAC that trades the AES/SHA hardware-acceleration question entirely for raw software speed. None of these alternatives make HMAC or CMAC obsolete. They mean the “right” MAC choice is really a family of related decisions: are you authenticating standalone data (HMAC, CMAC, KMAC) or authenticating alongside encryption you’re already doing (GMAC, Poly1305)?
Common Implementation Mistakes to Avoid
Most real-world MAC failures aren’t cryptanalytic breaks of HMAC or CMAC themselves; they’re engineering mistakes around them. A handful of patterns show up repeatedly enough to name directly.
- Timing-unsafe comparisons. Comparing a computed tag to the received tag with a standard string or byte-array equality check leaks timing information an attacker can exploit to forge a valid tag byte by byte. Every mainstream crypto library ships a constant-time comparison function; use it, every time, for both HMAC and CMAC verification.
- Silent truncation mismatches. A sender that truncates an HMAC-SHA256 tag to 128 bits and a verifier that expects the full 256-bit tag will either reject everything or, worse, accept forged short tags if the verification logic isn’t strict about expected length.
- Hand-rolled CMAC subkey derivation. The K1/K2 finite-field doubling step in CMAC is compact enough that developers sometimes reimplement it from a spec PDF rather than pulling in a validated library. Small errors in the reduction constant or the final-block branch logic reopen exactly the CBC-MAC forgery weakness CMAC exists to close.
- Key reuse across unrelated protocol domains. Using the same secret for both HMAC-signed webhooks and an internal HMAC-based session token means a compromise of one context compromises the other. Domain-separate keys, even when it’s tempting to reuse one secret for convenience.
- Assuming FIPS-mode availability without checking. A library that supports CMAC in general doesn’t necessarily expose it under a FIPS-validated provider build. Teams under compliance requirements need to verify the specific build and mode, not just the library name.
Real-World Deployments: Where Each One Actually Runs
Abstract security properties are one thing; what actually ships in production is another. Here’s where each algorithm shows up by name in specifications and vendor documentation.
HMAC in the wild
- JWT authentication. The HS256, HS384, and HS512 algorithm identifiers in the JSON Web Token spec are literally HMAC with the matching SHA-2 hash. Any app using JWTs with a shared secret is running HMAC on every request.
- AWS Signature Version 4. AWS’s request-signing process derives a signing key and computes an HMAC-SHA256 signature for every authenticated API call, from S3 uploads to Lambda invocations.
- GitHub webhooks. GitHub’s webhook validation uses HMAC-SHA256 and ships the result in an X-Hub-Signature-256 header so receiving servers can confirm a payload actually came from GitHub.
- HKDF. The HMAC-based key derivation function defined in RFC 5869 underpins key schedules in TLS 1.3 and other modern protocols, meaning HMAC is quietly load-bearing even in systems that don’t advertise it directly.
- IPsec and IKEv2. HMAC-based integrity and pseudorandom-function algorithms remain standard options in the IPsec ecosystem for VPN tunnels.
- Webhook signing across the payments industry. Beyond GitHub, the broader pattern of “HMAC-SHA256 over the raw request body, delivered in a signature header” has become the de facto standard for verifying inbound webhooks across e-commerce and payments platforms, precisely because both sender and receiver can implement it in a handful of lines regardless of tech stack.
CMAC in the wild
- Bluetooth Low Energy. BLE’s security procedures build on AES-CMAC-derived functions for pairing and key confirmation, which is why your phone can securely bond with a fitness tracker without a general-purpose hash library ever loading.
- EMV chip payment cards. AES-based EMV cryptographic profiles use CMAC-related authentication for transaction verification, alongside legacy MAC schemes still present in older deployments; the exact mechanism depends on the card’s EMV profile version.
- Automotive AUTOSAR Secure Onboard Communication. Vehicle CAN bus security profiles commonly specify AES-CMAC-based authenticators, typically truncated and paired with freshness counters to stop replay attacks on safety-critical messages.
- NIST SP 800-108 key derivation. NIST’s KDF framework lists both HMAC and CMAC-AES as approved pseudorandom functions, and NIST’s own validation listings include CMAC-AES-128, 192, and 256 alongside HMAC-SHA variants for this exact purpose.
- Constrained IoT and industrial control. Devices that already carry an AES coprocessor for payload encryption frequently reuse that same hardware for CMAC tagging rather than adding a separate hash engine.
- Wi-Fi security mechanisms. Specified integrity and key-management procedures in the 802.11 family of standards, the foundation WPA3 builds on, include AES-CMAC-derived functions for key-confirmation steps.
Cloud and Hardware Pricing: What It Costs to Run Either at Scale
Most teams don’t hand-roll HMAC or CMAC anymore; they call a managed key management service or a hardware security module. Here’s what that costs across the major providers as of late 2026.
| Provider / product | Per-operation cost | Key storage cost | Notes |
|---|---|---|---|
| AWS KMS | $0.03 per 10,000 GenerateMac/VerifyMac calls | $1.00 per HMAC key, per month | Same $1/month rate applies to symmetric, asymmetric, and HMAC keys |
| Google Cloud KMS (software-protected) | $0.03 per 10,000 MacSign/MacVerify operations | ~$0.06 per active key-version month | HSM-protected key versions run closer to $1.00-$2.50 per key-version month |
| Azure Key Vault Managed HSM | Billed under general Managed HSM operation meter | Varies by region and instance tier | No separate published HMAC/CMAC line item; check the regional pricing calculator |
| HashiCorp Vault Transit (self-hosted) | $0 per operation | Infrastructure cost only | Vault Enterprise licensing is quote-only, reportedly starting in the low five figures annually for small deployments |
| AWS CloudHSM | Not per-operation | ~$1.60 per HSM-hour, ~$1,168 per HSM-month | Production clusters typically require at least two HSMs |
| YubiHSM 2 | One-time hardware purchase | ~$650-$1,000 per unit | FIPS-validated variant typically runs higher |
| Thales Luna Network HSM | Quote-only | Tens of thousands of dollars, fully licensed | Includes support, partitions, and high-availability configuration |
At 10 million MAC operations a month, AWS KMS and Google Cloud KMS both land around $30 in pure operation charges, plus a trivial per-key monthly fee. That figure is nearly identical whether you’re generating HMAC or CMAC tags through these APIs, since both providers bill the same per-operation rate regardless of algorithm. The real cost divergence shows up when you need dedicated hardware: a CloudHSM cluster or a Luna appliance costs orders of magnitude more than API-based key management, and that expense is typically driven by compliance requirements, FIPS 140-3 Level 3 for instance, rather than by which MAC algorithm you picked.
Post-Quantum Considerations: Does Either Survive a Quantum Computer
Unlike RSA and elliptic-curve cryptography, HMAC and CMAC are symmetric-key primitives, and symmetric crypto is far less shaken by quantum computing. Shor’s algorithm, the one that threatens RSA and ECC, doesn’t apply here. The relevant quantum threat is Grover’s algorithm, which offers a quadratic speedup on brute-force key search, roughly halving the effective bit-security of a symmetric key in an idealized attack model.
Practically, that means a 128-bit key drops to something like 64-bit effective quantum security under Grover, which is why the conservative move for long-lived systems is to size up: use AES-256 rather than AES-128 as the CMAC cipher, and use HMAC-SHA512 rather than HMAC-SHA256 when a system needs to stay secure for decades. Neither HMAC nor CMAC is “broken” by quantum computers the way RSA and ECC are; their security margin just gets thinner, and the fix is bigger keys and bigger hash outputs rather than a wholesale algorithm swap. If you’re also touching asymmetric key exchange in the same system, that’s a different and more urgent migration story, covered in our RSA vs ML-KEM breakdown.
Library and Language Support in 2026
HMAC support is close to universal. CMAC support is real but noticeably less consistent across mainstream language standard libraries, which is worth knowing before you commit a protocol design to it.
| Language / platform | HMAC support | CMAC support |
|---|---|---|
| OpenSSL | Native HMAC API and EVP MAC interface | Available via EVP/provider interface, version-dependent |
| Python | Built into hmac and hashlib modules | cryptography.hazmat.primitives.cmac (third-party package) |
| Java | javax.crypto.Mac with HmacSHA256 and similar | javax.crypto.Mac with provider-dependent AESCMAC naming |
| Go | Standard library crypto/hmac | No standard library package; requires a maintained external module |
| Node.js | Native crypto.createHmac() | No first-class native API; requires a maintained package |
| libsodium | Keyed hashing via BLAKE2b APIs, not classic HMAC-SHA2 | No general-purpose AES-CMAC API in the standard high-level API |
// Node.js: HMAC-SHA256, available natively
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(payload);
const tag = hmac.digest('hex');
// Python: AES-CMAC via the cryptography package (not in hashlib)
from cryptography.hazmat.primitives import cmac
from cryptography.hazmat.primitives.ciphers import algorithms
c = cmac.CMAC(algorithms.AES(aes_key))
c.update(payload)
tag = c.finalize()
That asymmetry in tooling is a real engineering cost. If your team is shipping a Node.js or Go backend and picks CMAC for “performance,” budget time for vetting a third-party package rather than assuming it’s a one-line standard-library call the way HMAC is.
Migration Guide: Moving Between HMAC and CMAC
Teams rarely migrate a live protocol from HMAC to CMAC or the reverse, but it does happen, usually driven by new hardware constraints or a compliance mandate. Here’s the practical path.
- Inventory every place the current MAC is computed and verified. Include client SDKs, server middleware, log-signing jobs, and any offline batch verification tools. Missed call sites are the most common cause of migration outages.
- Add a protocol version or algorithm identifier field if one doesn’t already exist, so verifiers can tell which MAC scheme produced a given tag during the transition window.
- Deploy dual verification first. Accept both the old and new tag formats on the receiving side before any sender starts producing the new format. This is the same pattern used for TLS cipher suite migrations.
- Rotate keys, don’t reuse them across algorithms. An HMAC key and a CMAC key should never be the same secret material; generate fresh keys sized appropriately for the new construction, an AES-256 key for CMAC, or a hash-matched key length for HMAC.
- Update key management infrastructure. If you’re moving from software HMAC to hardware-backed CMAC, confirm your HSM or cloud KMS actually supports CMAC operations; not every provider’s basic tier does, per the library table above.
- Flip senders to the new format in stages, monitoring verification failure rates as you go, then remove support for the old format only after telemetry shows zero legacy traffic for a full billing or audit cycle.
- Document the change in your cryptographic bill of materials. Auditors and compliance reviewers will ask why the algorithm changed; have the hardware or standards justification ready.
Pros and Cons
HMAC
Pros: near-universal library support across every mainstream language, straightforward to implement correctly, scales tag length with the hash you choose, doubles as the foundation for HKDF key derivation, and is the default choice in essentially every modern web API standard.
Cons: on AES-only hardware with no SHA acceleration, it can lag CMAC in raw throughput, and FIPS 198-1’s pending retirement in favor of SP 800-224 means documentation referencing “the HMAC standard” needs to be kept current.
CMAC
Pros: extremely efficient on hardware that already has an AES coprocessor, tag generation piggybacks on silicon many embedded and payment devices already carry, and it’s the natural fit for protocols that mandate AES throughout the stack.
Cons: fixed 128-bit tag ceiling regardless of key size, inconsistent standard-library support in Go and Node.js, and a subkey-derivation step that’s easy to get wrong if a team implements it from scratch instead of using a validated library.
Use-Case Recommendations
- Web API authentication and JWT signing: use HMAC-SHA256. It’s what the JWT spec expects (HS256), every major language has it built in, and there’s no AES coprocessor advantage to chase on a general-purpose server.
- Webhook payload verification (Stripe-style, GitHub-style): use HMAC-SHA256. Verification happens on arbitrary receiving infrastructure that may not have any AES acceleration guarantee, and HMAC’s ecosystem breadth means every downstream consumer can verify it trivially.
- Bluetooth Low Energy accessories and smart locks: use CMAC. The Bluetooth spec already mandates it, and the AES hardware needed for link encryption is already present on the chip.
- Automotive CAN bus and AUTOSAR-compliant ECUs: use CMAC, truncated per your safety profile’s freshness-counter design. This is standard practice in the automotive security community and matches what AUTOSAR’s Secure Onboard Communication module expects.
- Payment terminal and EMV-adjacent firmware: use CMAC where your EMV profile specifies it. Don’t substitute HMAC into a payment protocol that names CMAC explicitly; compliance certification depends on matching the specified primitive exactly.
- Key derivation functions under NIST SP 800-108: either works, since NIST approves both HMAC and CMAC-AES as PRFs for this purpose; pick whichever primitive your existing codebase already trusts to avoid adding a second crypto dependency.
- Constrained IoT sensors with an AES-only crypto engine: use CMAC. Adding a software SHA-256 implementation to a chip that only has AES silicon wastes flash space and battery life for no security benefit.
The Verdict
There’s no universal winner here, and anyone telling you there is hasn’t shipped both in production. HMAC-SHA256 is the right default for web-facing software, API signing, JWTs, webhooks, and key derivation, because the tooling is everywhere and the performance gap disappears on any server CPU built in the last several years. CMAC earns its place specifically where AES hardware already exists and adding a hash engine would be wasted silicon: Bluetooth accessories, EMV payment hardware, and automotive ECUs.
If you’re building a new system today and have no hardware constraint pulling you toward AES-only silicon, start with HMAC-SHA256. It’s the safer default precisely because it’s the one every library, auditor, and downstream integrator already understands. Reach for CMAC only when a protocol you don’t control, Bluetooth, EMV, AUTOSAR, mandates it, or when you’re designing embedded hardware from scratch and can verify the AES coprocessor math actually saves you the silicon budget it promises.
One more data point worth weighing before you commit: switching MAC algorithms mid-project is expensive in a way that switching many other technical decisions isn’t, because it touches every client that has ever integrated with your system. That asymmetry argues for spending real time on this decision up front rather than treating it as a detail to revisit later. Teams that get it wrong tend to discover the mistake at the worst possible moment, during a compliance audit, a hardware bill-of-materials review, or a scramble to add CMAC support to a language ecosystem that never prioritized it.
Frequently Asked Questions
Is CMAC more secure than HMAC?
No. Both are NIST-approved and neither has a known practical break as of September 2026. Security depends far more on correct implementation, adequate key length, and proper truncation handling than on which of the two you choose.
Can I use HMAC and CMAC together in the same system?
Yes, and many systems do, using HMAC for API-layer authentication and CMAC for hardware-level operations like secure boot or Bluetooth pairing. Just never reuse the same key material across both algorithms.
Why does JWT use HMAC instead of CMAC for HS256?
The JWT specification was designed for general-purpose web software where SHA-based hashing is universally available and AES hardware acceleration can’t be assumed. HMAC’s ecosystem breadth made it the obvious fit when the standard was written.
Does AES-256-CMAC produce a stronger tag than AES-128-CMAC?
No. Both produce a 128-bit tag because that’s fixed by AES’s block size. AES-256 gives you a stronger underlying key against brute-force key search, not a larger or stronger output tag.
Is HMAC vulnerable to length-extension attacks?
No. Length extension affects naive constructions like a raw SHA256(key + message) hash, not HMAC. HMAC’s nested double-hash structure was specifically designed to eliminate that vulnerability.
Which is faster on a typical cloud server, HMAC-SHA256 or AES-CMAC?
On modern cloud instances with both SHA and AES hardware extensions active, common on current AWS Graviton, Intel, and AMD server chips, the gap is small and workload-dependent. On AES-only embedded hardware, CMAC tends to win by a wide margin because the chip is already built to accelerate it.
Do AWS KMS and Google Cloud KMS charge differently for HMAC versus CMAC?
No. Both providers bill per-operation and per-key-month at the same published rate regardless of which MAC algorithm the key uses. The cost driver that actually varies is whether the key is software-protected or HSM-protected.
Will quantum computers break HMAC or CMAC?
Not in the way they threaten RSA or ECC. Grover’s algorithm offers only a quadratic speedup against symmetric keys, so the practical response is to use longer keys and hash outputs, AES-256 and HMAC-SHA512 for long-lived systems, rather than replacing the algorithm entirely.
Should I use GMAC or Poly1305 instead of HMAC or CMAC?
Only if you’re already using AES-GCM or ChaCha20-Poly1305 for encryption in the same system. GMAC and Poly1305 are built for authenticating data alongside an encryption operation you’re already performing; HMAC and CMAC remain the better fit for standalone authentication where no encryption is involved.




