Part 3 · 2 chapters · ~12 min
Digital Signatures
What signatures prove (authenticity, integrity, non-repudiation), signing hashes of messages, Ed25519, ECDSA and its nonce pitfalls, RSA-PSS, measured costs, canonicalisation before signing, and uses in tokens, certificates, packages and documents.
6
What signatures prove, and what they cost
code
import { generateKeyPairSync, sign, verify } from 'node:crypto';
const { privateKey, publicKey } = generateKeyPairSync('ed25519');
const letter = Buffer.from(JSON.stringify({ loan: 'LN-81723', status: 'cleared', issued: '2026-10-06' }));
const sig = sign(null, letter, privateKey); // 64 bytes
verify(null, letter, publicKey, sig); // true; change one byte of letter → falseSIGNATURES, MEASURED
microseconds per operation on this machine (Node, OpenSSL)
swipe the figure sideways, or tap expand for full screen
1/4
what a signature proves
A signature, made with a private key over a message, proves that the holder of that key signed exactly this message. Anyone with the public key can verify; nobody without the private key can forge.
who signed, and exactly whatverifiable by anyone with the public key
7
Pitfalls
| pitfall | consequence | avoid by |
|---|---|---|
| ECDSA nonce reuse or bias | the private key can be computed from two signatures (Sony PS3, 2010) | Ed25519 or deterministic ECDSA (RFC 6979) |
| signing non-canonical data | JSON with different key order or whitespace verifies differently | sign exact bytes; canonicalise (JCS) or sign a hash of stored bytes |
| not checking which key | a valid signature by the wrong key accepted | pin keys or check the certificate chain and key id |
| RSA PKCS#1 v1.5 padding | historical forgery and padding attacks | RSA-PSS for new signatures |