HTTP Message Signatures

A Visual Guide to RFC 9421

Abstract

This document describes a mechanism for creating, encoding, and verifying digital signatures or message authentication codes over components of an HTTP message. This mechanism supports use cases where the full HTTP message may not be known to the signer and where the message may be transformed (e.g., by intermediaries) before reaching the verifier.

How-Tos

End-to-End HTTP Message Signature Exchange

A step-by-step guide for a client to sign an HTTP request and for a server to verify it.

Section 1: Setup and Configuration

  1. Agree on a Security Policy: Client and server must agree on components to sign, allowed algorithms, and key identifier format.
  2. Provision Key Material: Establish shared secrets (for HMAC) or exchange public keys (for RSA/ECDSA).

Section 2: Client-Side (Signing)

  1. Prepare the HTTP Request: Construct the request with all headers to be signed.
  2. Create the Signature Base: Build the canonical string to be signed, including the special `@signature-params` line.
  3. Generate the Signature: Compute the signature of the base string using the private key or shared secret.
  4. Attach Signature to Request: Add `Signature-Input` and `Signature` headers to the request.
  5. Send the Request: Transmit the complete signed request to the server.

Section 3: Server-Side (Verifying)

  1. Parse Signature Headers: Extract signature metadata and the received signature value.
  2. Enforce Security Policy: Check if the signature parameters meet the application's policy.
  3. Retrieve Verification Key: Use the `keyid` to look up the client's public key or shared secret.
  4. Reconstruct the Signature Base: Rebuild the signature base from the received request exactly as the client did.
  5. Verify the Cryptographic Signature: Perform cryptographic verification and check parameters like timestamps.
  6. Accept or Reject the Request: Process the request if valid; otherwise, reject with a 401 or 403 status code.

How to Create the Signature Base

The process for combining canonicalized message components into the final signature base string.

  1. Define Covered Components: Create an ordered list of component identifiers to be signed.
  2. Canonicalize Each Component Value: For each identifier, derive and canonicalize its value from the HTTP message.
  3. Construct Component String Lines: Create a line for each component: `"identifier": value`.
  4. Construct the `@signature-params` Line: Create the special line containing the list of covered components and other signature metadata.
  5. Combine All Lines: Concatenate all lines, separated by newlines, to form the final signature base.

Core Definitions

Signer

The entity that is generating or has generated an HTTP message signature.

Verifier

An entity that is verifying or has verified an HTTP message signature against an HTTP message.

Signature Base

The sequence of bytes generated by the signer and verifier using the covered components set and the HTTP message.

Covered Components

An ordered set of HTTP message component identifiers that indicates the set of message components covered by the signature.

Derived Component

A component derived from the message's control data (e.g., `@method`, `@path`) rather than a literal header value.

Signature Context

The data source from which component values are drawn, including the target message and other known information.

Frequently Asked Questions

Related Organizations

Internet Engineering Task Force (IETF)

A large open international community concerned with the evolution of the Internet architecture.

Internet Assigned Numbers Authority (IANA)

A standards organization that oversees global IP address allocation, DNS root zone management, and other IP-related symbols.

Related Standards

Transport Layer Security (TLS)

A cryptographic protocol for providing communications security over a network.

JSON Web Signature (JWS)

A standard for representing content secured with digital signatures or MACs using JSON.

RFC 8941 (Structured Fields)

Defines a common syntax for structured data in HTTP header fields.