liveBook · Manning

Message authentication code

As explained in Real-World Cryptography

An authentication tag is the deterministic output of a keyed authentication function used to verify a message's integrity and authenticity.

A message authentication code (MAC) protects a message’s integrity and authenticity with a shared secret key. It turns a message and key into a deterministic authentication tag: the same key and message produce the same tag, while someone without the key should not be able to forge one. section 3.0 section 3.1

Protecting a stateless cookie

A server can place a username and its authentication tag in a browser cookie. When the cookie returns, the server recomputes the tag from its secret key and the received username. A modified username produces a different tag, so the server rejects the request. A public hash alone fails because an attacker can modify the username and recompute its hash. section 3.1

A basic MAC exchange follows these steps:

  • Share the same secret key between the sender and receiver. section 3.2
  • Compute an authentication tag from the key and message. section 3.1
  • Send the message together with its tag. section 3.2
  • Recompute the tag and compare it with the received tag using a constant-time verification function. section 3.3.4 section 3.7
Figure 3.3 The interface of a message authentication code (MAC). The algorithm takes a secret key and a message, and deterministically produces a unique authentication tag. Without the key, it should be impossible to reproduce that authentication tag.

Shows the MAC interface: a secret key and message deterministically produce an authentication tag that should be unreproducible without the key. section 3.1

A MAC does not provide confidentiality: an observer may still read the message. Its primary guarantee is resistance to forgery, even when an attacker can request tags for many chosen messages. Keep the key random and secret, serialize structured data unambiguously, and use tags of at least 128 bits. section 3.3.1 section 3.3.2

Avoid these common MAC failures:

  • Do not authenticate messages with a public hash alone; attackers can recompute it after tampering. section 3.1
  • Do not use a naïve MAC protocol when an old valid message could be accepted again; add an incrementing counter or another replay protection mechanism. section 3.3.3
  • Do not compare tags with an ordinary early-exit comparison; timing differences can reveal the tag byte by byte. section 3.3.4
  • Do not construct a MAC by hashing a secret and message casually; use a standardized construction such as HMAC or KMAC. section 3.7

HMAC in practice

HMAC is a widely used MAC built from a hash function, commonly SHA-2. In a Rust exchange, the sender computes HMAC-SHA256 over the message, and the receiver independently verifies the received tag with the same key. The protocol authenticates integrity but still permits replay unless the message includes suitable freshness data. section 3.2 section 3.5.1

Listing 3.1 Sending an authenticated message in Rust
use sha2::Sha256;
use hmac::{Hmac, Mac, NewMac};
 
fn send_message(key: &[u8], message: &[u8]) -> Vec<u8> {
    let mut mac = Hmac::<Sha256>::new(key.into());          #1
 
    mac.update(message);                                    #2
 
    mac.finalize().into_bytes().to_vec()                    #3
}

Provides a small sending example that creates an HMAC tag from a key and message. section 3.2

Listing 3.2 Receiving an authenticated message in Rust
use sha2::Sha256;
use hmac::{Hmac, Mac, NewMac};
 
fn receive_message(key: &[u8], message: &[u8],
  authentication_tag: &[u8]) -> bool {
    let mut mac = Hmac::<Sha256>::new(key);         #1
    mac.update(message);                            #2
 
    mac.verify(&authentication_tag).is_ok()
}

Provides the matching receiving example that recomputes and verifies an HMAC authentication tag. section 3.2

How Real-World Cryptography covers it

How deep it goes
Explains keyed tags, forgery, tag length, replay, timing attacks, HMAC, and KMAC, while deferring formal proof details.
Examples
Uses stateless cookies, two-party messages, Rust HMAC code, replay counters, and constant-time comparison code.
What it assumes
Assumes familiarity with hash functions and begins MAC usage with plain-language cookie and message examples.
What you can do after
Apply HMAC to authenticate messages and verify tags safely while accounting for replay, serialization, length, and timing risks.
How it connects
Connects MACs with hash functions, HMAC, KMAC, authentication tags, replay attacks, timing attacks, and key derivation.

Also explained in

Compare how 4 books explain message authentication code →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Real-World Cryptography. The section links point to the parts of the book it draws on.