liveBook · Manning

Digital signature

As explained in API Design Patterns

A digital signature is a cryptographic value generated with a private key and verifiable with the corresponding public key to authenticate the signer and detect changes to signed data.

A digital signature is a cryptographic value generated with a private key and verified with the corresponding public key. Signing proves possession of the private credential, while tying the signature to message bytes makes any alteration detectable. Unlike shared secrets or HMAC, asymmetric credentials support third-party verification and prevent the sole signer from plausibly claiming that the signature was forged. section 30.0 section 30.2

Use digital signatures for authenticated API requests through this sequence:

  • Generate an asymmetric public-private keypair, then register the public key with the API and receive a user or key identifier. section 30.3 section 30.3.2
  • Create a deterministic request fingerprint from the method, path, host, date, and body digest; sign that exact string with the private key. section 30.3.4 section 30.3.3
  • Attach a digest header and a signature header containing the ordered signed headers, key identifier, algorithm, and signature value. section 30.3.5
  • Verify the body digest, recompute the fingerprint using the declared order, select the registered public key, and reject requests whose signature does not validate. section 30.3.6

Signing a resource update

A client updates /chatRooms/1 with PATCH. It hashes the JSON body into a Digest header, fingerprints the request as `(request-target): patch /chatRooms/1`, together with host, date, and digest, then signs that fingerprint using `rsa-sha256`. The Signature header identifies key `1234`, records the exact header order, and carries the resulting signature. The server independently reconstructs those bytes before accepting the update. section 30.3.4 section 30.3.5

Figure 30.1 Sequence of registering an account with a public key

The registration sequence clarifies how a public key becomes the identity used for later signature verification. section 30.3.2

Listing 30.5 Generating a fingerprint given a HTTP request
const HEADERS = ['(request-target)', 'host', 'date', 'digest'];
 
function generateRequestFingerprint(
    request: HttpRequest, headers = HEADERS): string {
  return headers.map((header) => {
    let value;
    if (header === '(request-target)') {                          #1
      value = `${request.method.toLowerCase()} ${request.path}`;
    } else if (header === 'digest') {                             #2
      value = generateDigestHeader(request.body);
    } else {                                                      #3
      value = request.headers[header];
    }
    return `${header.toLowerCase()}: ${value}`;                   #4
  }).join('\n');
}

The fingerprint listing makes canonical request construction concrete, including the special request target and body digest. section 30.3.4

How API Design Patterns covers it

How deep it goes
Explains key registration, raw signing, request fingerprinting, signature metadata, and verification, while largely deferring cryptographic mathematics.
Examples
Uses Node.js signing and verification functions, public-key registration, and a signed PATCH request for `/chatRooms/1`.
What it assumes
Assumes HTTP request structure and asymmetric credentials, while introducing signature generation, registration, fingerprinting, and verification.
What you can do after
Builds an API flow that registers public keys, signs outbound requests, and authenticates inbound requests.
How it connects
Connects asymmetric credentials, HTTP requests, request fingerprinting, hashing, public keys, HMAC, and shared secrets.

Also explained in

Compare how 8 books explain digital signature →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of API Design Patterns. The section links point to the parts of the book it draws on.