liveBook · Manning

Digital signature

As explained in Grokking Web Application Security

A cryptographic signature is data generated with a private key that enables verification of a message's authenticity and integrity using the corresponding public key.

A digital signature makes tampering visible. It is data generated with a private key that lets a recipient use the corresponding public key to verify a message’s authenticity and integrity. In web applications, this matters when data travels through a client-controlled location such as a cookie or JWT: an attacker may edit a username, role, or other session value before sending it back. section 9.10 section 14.8

Treat signed client-side data as untrusted until its signature has been validated. A server accepting a JWT must validate its signature before using it as an authentication token; otherwise, altered content can be mistaken for legitimate session state. Signing protects against modification, not disclosure: clients can still read a digitally signed cookie or JWT. section 9.10 section 9.11

Use signatures where data can be changed outside server control:

  • Tamperproof client-side session cookies, or encrypt them when their contents must remain secret. section 9.3 section 9.11
  • Sign JWT payloads and verify the signature in every microservice that accepts the token. section 9.10
  • Sign serialized content received from untrusted sources when a signature is needed to prevent data tampering. section 11.16
  • Use DKIM for outgoing email by publishing a public key in DNS and signing mail with the matching private key. section 14.8

Rejecting an altered session cookie

A signed cookie can contain a value followed by its signature. To verify it, separate the tentative value, generate the expected signed form with the secret, and compare it with the received input. If the comparison fails, return false rather than accepting the changed session value. The shown Node.js implementation also uses a timing-safe comparison. section 9.10

/**
* Unsign and decode the given `input` with `secret`,
* returning `false` if the signature is invalid.
*/
exports.unsign = function(input, secret){
 var tentativeValue = input.slice(0, input.lastIndexOf('.')),
     expectedInput  = exports.sign(tentativeValue, secret),
     expectedBuffer = Buffer.from(expectedInput),
     inputBuffer    = Buffer.from(input);
 return (
   expectedBuffer.length === inputBuffer.length &&
   crypto.timingSafeEqual(expectedBuffer, inputBuffer)
 ) ? tentativeValue : false;
};

This verification routine shows the decision point that matters: recover the original value only when the received signed input matches the expected signature; otherwise reject it. section 9.10

Signing and encryption solve different problems. Use a signature to detect unauthorized changes. Encrypt, or keep data outside the client-side session, when users must not be able to read it. Pair either choice with normal session defenses such as HTTPS, Secure cookies, HttpOnly cookies, strong server-generated session IDs, and current framework patches. section 9.11

How Grokking Web Application Security covers it

How deep it goes
Explains verification through cookie unsigning and DKIM key placement, without cryptographic algorithm internals.
Examples
Uses an altered username cookie, a Node.js cookie-parser unsign routine, JWT validation, and DKIM-signed email.
What you can do after
Apply it via cookie-parser or DKIM services to reject altered session data, tokens, and email.
How it connects
Connects digital signatures with client-side sessions, JWTs, HMAC, encryption, DKIM, DNS, and serialized content.

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 Grokking Web Application Security. The section links point to the parts of the book it draws on.