4 Message Integrity and Authentication
This chapter introduces developers to practical cryptographic building blocks for ensuring message integrity and authenticating senders, using clear Java examples rather than deep math. It frames security around four goals—integrity, authentication, confidentiality, and non-repudiation—and focuses here on the first two. Through a running ACME refunds scenario, it shows how cryptographic hash functions (SHA-2 and SHA-3) reliably detect accidental data corruption, and why that alone is insufficient when an attacker can alter both a file and its accompanying checksum.
The text explains what makes a cryptographic hash function suitable for security: determinism, one-way resistance, and collision resistance. It surveys the SHA family’s evolution (with SHA-1 deprecated), encourages using modern standards with at least 256-bit outputs, and stresses algorithm agility—designing data formats and systems so hash algorithms can be upgraded safely without enabling downgrade attacks. To defend against active tampering and to confirm the sender’s identity, the chapter introduces Message Authentication Codes, with HMAC as the standard, secure construction. HMAC mixes a shared secret with message data in a carefully defined way (not simple concatenation), providing integrity plus authenticity—but not confidentiality or non-repudiation—while highlighting the need for strong, well-managed keys.
On the implementation side, the chapter uses Java’s Cryptography Architecture and Extensions (JCA/JCE) to compute hashes via MessageDigest and HMACs via Mac with standard algorithm names (for example, SHA-256, SHA3-256, HmacSHA256). It advises avoiding legacy MD5 and SHA-1 except for historical data, warns about common misconfigurations, and notes developer-friendly libraries that wrap JCA/JCE as well as performance-optimized providers. The ACME examples demonstrate end-to-end flows: producing a file and its hash/HMAC, then verifying on receipt before processing. Taken together, these practices equip developers to detect corruption, resist tampering, and authenticate message origin—capabilities foundational to higher-level protocols such as JWT and TLS.
A typical e-commerce high level architecture. Customers place orders using the ACME Inc. web applications, which calls the Payments Inc. credit card API to collect payments from customers while processing an order.
ACME Inc. staff approve refunds using the warehouse management application. Once a day the warehouse management application generates a refunds.json file. The payment service refunds customer credit cards for the amount specified in the refunds.json file.
Think of the hash function as a blender that takes inputs of different sizes to produce outputs of the same size. Different input values produce completely different output values. Attackers with access to the hash value cannot determine anything about the input.
Detecting data integrity violation using a cryptographic hash function. The foo.txt producer computes the hash value of the content and then writes it to foo.txt.sha256. A consumer computes the SHA-256 value of the contents of foo.txt and then compares the computed value to the expected value in foo.txt.sha256. If expected and actual values match, the file is valid; if not, the file is corrupt.
Files on maven central. Notice the sha1 and md5 files that contain hashed values of the corresponding artifacts. MD5 and SHA-1 are insecure, but they are still used by maven central for backward computability reasons.
Application code calls the standard JCA and JCE APIs making the application code independent of the implementation of the crypto algorithm. The JCA and JCE layer routes call to a provider’s implementation. Java 11 based OpenJDK ships with 13 providers out of the box.
ACME Inc. staff approve refunds using the warehouse management application. Once a day, the warehouse management application generates a refunds.json file. The payment service issues refunds to customer credit cards for the amount specified in the refunds.json file.
Message Authentication Code (MAC) is data added to the end of a message that can be used by the receiver of a message to identify who sent the message and that the message was not tampered with.
Computing the Message Authentication Code (MAC) requires both the secret key and the input message. When the hacker modifies the input, they cannot compute the MAC because they don’t know the secret key that is part of the computation. Since they can’t compute the MAC they can’t fool the receiver with a fake message body.
ACME Inc. staff approve refunds using the warehouse management application. Once a day the warehouse management application generates a refunds.json file. The payment service issues refunds to customer credit cards for the amount specified in the refunds.json file.
Determine who created a file and that the file was not tampered with using a Hashed Message Authentication Code (HMAC). The producer of the foo.txt file computes the HMAC-SHA-256 value of the content and writes it to foo.txt.hs256. A consumer computes the SHA-256 value of the contents of foo.txt then compares the computed value to the expected value in foo.txt.hs256. If the computed and expected HMAC values differ, then foo.txt has been tampered with and an error should be raised.
Summary
- Cryptography solves four fundamental security problems: integrity (data unchanged), authentication (sender identity), confidentiality (data privacy), and non-repudiation (legal proof of transactions).
- Cryptographic hash functions like SHA-2 and SHA-3 produce fixed-size outputs from any input and have one-way properties and collision resistance, making them ideal for detecting data corruption.
- Hash functions are deterministic, always producing the same output for the same input, but different inputs produce completely different outputs.
- SHA-1 and MD5 are deprecated due to security vulnerabilities, while SHA-2 and SHA-3 are currently considered secure for new applications.
- Cryptographic hash functions can detect accidental data corruption but cannot prevent active tampering by attackers who modify both data and hash files.
- Message Authentication Code (MAC) requires a secret key shared between sender and receiver to guarantee both integrity and authenticity of messages.
- Hashed Message Authentication Code (HMAC) is a secure way to build MAC using cryptographic hash functions and secret keys, widely used in protocols like TLS and JWT.
- Java Cryptography Architecture (JCA) and Java Cryptography Extensions (JCE) provide cryptographic support through a provider-based architecture with standardized APIs.
- Simple concatenation of secret keys with messages before hashing is insecure with some algorithms, while HMAC provides a secure mixing approach for all supported hash functions.
- Applications should design for hash function upgrades since algorithms become insecure over time, requiring version fields and migration strategies.
- HMAC enables detection of both accidental corruption and active tampering, as attackers cannot forge valid HMAC values without knowing the secret key.
- Secret keys for HMAC should be stored securely in credential management systems rather than hardcoded in configuration files to prevent theft.
Software Security for Developers ebook for free