pk.org: Computer Security/Lecture Notes

Public Key Cryptography and Integrity

Part 3 - Integrity Mechanisms

Paul Krzyzanowski – 2025-09-19

Part 1: Public Key Cryptography
Part 2: Hash functions
Part 3: Integrity Mechanisms
Part 4: Diffie-Hellman
Part 5: Putting It All Together
Part 6: Quantum Attacks and Post-Quantum Cryptography


Part 2 closed with the limitation that hashes alone cannot prevent forgery. This brings us to the two main tools that provide cryptographic integrity: message authentication codes (MACs) and digital signatures. Both ensure that data has not been altered in transit, but they use different key structures and provide different guarantees.

Hash functions give us a compact fingerprint of data. If we hash a file and store the result, we can later recompute the hash to check whether the file changed. This protects against accidental corruption, but it does not defend against an active adversary. An attacker who can modify the file can also recompute its hash. We need stronger tools that tie integrity to a secret that the attacker cannot forge. Two approaches are widely used: message authentication codes (MACs) and digital signatures.


Message Authentication Codes (MACs)

A message authentication code is a value computed from a message and a secret key. The sender computes the MAC and sends it along with the message. The receiver, who knows the same secret key, recomputes the MAC. If the values match, the receiver is confident that the message has not been altered.

How MACs Work

A MAC function takes two inputs: the message \(m\) and a key \(k\). It produces a fixed-size output, \(MAC_k(m)\). Because only parties who know \(k\) can produce the correct output, this provides both integrity and authenticity.

Examples

HMAC (Hash-based Message Authentication Code):

HMAC is standardized in RFC 2104 and is the most widely used MAC construction today. It wraps a cryptographic hash function, such as SHA-256, in a secure structure. Simply hashing a message concatenated with a key is insecure because many hash functions are vulnerable to extension attacks. HMAC solves this problem by hashing the message twice with two different versions of the key. One version of the key is combined with an inner pad constant and the other with an outer pad constant.

The process is: \[H((K \oplus opad) \; || \; H((K \oplus ipad) \; || \; m))\] where \(H\) is the hash function, \(K\) is the secret key (padded as needed), \(opad\) and \(ipad\) are fixed constants, and \(||\) means concatenation.

This structure ensures that the MAC is secure as long as the underlying hash function remains secure. HMAC is used in TLS, IPsec, SSH, and many APIs for web services.

CMAC (Cipher-based Message Authentication Code):

CMAC is defined in NIST Special Publication 800-38B. It is based on a block cipher such as AES.

A common way to build a MAC from a block cipher is to run the cipher in CBC mode over the message and then keep only the last ciphertext block as the MAC. This works because each ciphertext block depends on all the preceding plaintext blocks through chaining. This technique is called CBC-MAC.

CMAC strengthens this idea by defining how keys are derived and how padding is handled, eliminating weaknesses in basic CBC-MAC. CMAC is commonly used in embedded systems and standards such as IEEE 802.11 (Wi-Fi) security.

Strengths and Limitations

MACs offer several advantages but also come with trade-offs.

The drawback is that MACs do not provide non-repudiation. Any party who shares the key could have generated the MAC, so there is no way to prove uniquely which party created a message.


Authenticated Encryption with Associated Data (AEAD)

In the previous lecture on block cipher modes, we introduced AEAD: schemes that combine symmetric encryption with built-in integrity protection. Instead of encrypting a message and then appending a separate MAC, AEAD produces both the ciphertext and an authentication tag in one process.

Two important examples are widely deployed:

AEAD modes are efficient and widely adopted in practice. For example, TLS 1.3 mandates AEAD: every secure web session uses either AES-GCM or ChaCha20-Poly1305. These modes illustrate that integrity is not limited to separate MACs or digital signatures. It can also be built directly into the encryption process.


Digital Signatures

MACs work well when two parties already share a secret key, but they do not scale beyond that setting and they do not provide non-repudiation. If you want to prove to the world that you, and only you, authored a message, you need digital signatures, which rely on public key cryptography.

How Signatures Work

A digital signature scheme has three steps:

  1. Signing: The sender computes a hash of the message. The hash is then encrypted with the sender’s private key to form the signature.
  2. Transmission: The sender sends both the message and the signature.
  3. Verification: The receiver decrypts the signature using the sender’s public key, obtaining the claimed hash. The receiver then recomputes the hash of the received message. If the values match, the signature is valid.

This description captures the intuition but is too simple for practice. If we literally just raised a hash to the private exponent in RSA, the scheme would be vulnerable. The hash might be shorter than the modulus, and without padding an attacker could forge valid-looking signatures.

For this reason, real systems use carefully designed signature algorithms that wrap the core idea in padding, randomness, or special curve operations. These algorithms guarantee security even against attackers who can request signatures on chosen messages.

Guarantees

Digital signatures provide:

Examples

While the concept can be summarized as “a digital signature is an encrypted hash,” in practice, signatures use dedicated algorithms with padding, randomness, and well-defined rules. These refinements ensure that signatures remain secure even against adaptive adversaries who can request signatures on chosen messages.

Real-World Use

Some common examples of how digital signatures are used in real life include:


Comparing MACs and Signatures

Property MACs (symmetric) Signatures (asymmetric)
Key type Shared secret Public/private key pair
Efficiency Very fast Slower
Integrity Yes Yes
Authenticity Yes (to parties who know the key) Yes (verifiable by anyone with the public key)
Non-repudiation No Yes
Common uses Secure channels, protocols, file transfers Software distribution, certificates, contracts

Why Hashes Are Always Involved

In practice, digital signatures are not applied to entire messages directly. Instead, the message is first hashed, and the signature is created over the hash value. This has two reasons:

This is why standards always specify a pair: a hash function (such as SHA-256) and a signature algorithm (such as RSA or ECDSA).


Example: Verifying a Signed Email

Suppose you receive an email with an attached digital signature:

  1. You hash the email body using SHA-256.
  2. You use the sender’s public key to decrypt the attached signature, obtaining a claimed hash.
  3. If the two values match, the email is authentic and intact.

If the email were modified in transit, the recomputed hash would not match the decrypted signature. If someone tried to forge the signature, they would need the sender’s private key, which is not available.


Review

Hash functions provide fingerprints of data but cannot by themselves protect against active adversaries.

Together, these approaches give us the tools to guarantee that data has not been altered and that it truly comes from its claimed source.


Next: Part 4: Diffie-Hellman