Asymmetric · 06

Digital Signatures

Same math as asymmetric encryption, used in the opposite direction. The private key creates the signature. The public key verifies it. Anyone can check. Only the owner can produce. This is how your browser knows the certificate it just received actually belongs to your bank.

01

What A Signature Proves

A valid digital signature on a message proves three things: the signer had access to the private key (authenticity), the message was not modified after signing (integrity), and the signer cannot later deny having signed (non-repudiation).

One thing it does not prove: confidentiality. A signed message is not encrypted. Anyone can read it. Signing and encrypting are independent operations; you can do either, both, or neither, depending on what you need.

PropertyWhat it means
AuthenticityThe signature could only have been produced by someone with the private key.
IntegrityAny change to the message, even a single bit, invalidates the signature.
Non-repudiationThe signer cannot credibly claim they did not sign, because verification is publicly checkable.
02

Sign With Private, Verify With Public

The directional rule is the mirror of encryption:

Figure 6.1: Sign and verify flow Two boxes. On the left, Alice combines her message with her private key to produce a signature. The message and signature are sent across the network. On the right, Bob (or anyone) combines the received message with Alice's public key to verify the signature, producing a true or false result. ALICE SIGNS ANYONE VERIFIES message private key sign() message + signature verify() true false public key verify() returns true if the signature was produced from this message by the key paired to this public key
Fig 6.1 · Sign with private, verify with public

This is the source of the most common student confusion in asymmetric crypto: "wait, you encrypt with public but sign with private?" Yes. Same key pair, opposite directions, opposite security properties. The mnemonic from the Foundations page bears repeating: encrypt to a public key, sign with a private key.

03

Hash First, Then Sign

No real signing algorithm signs the raw message. They all hash the message first, then sign the hash. Three reasons:

The pattern is universal:

signature = sign(private_key, SHA-256(message))

valid = verify(public_key, SHA-256(message), signature)

The hash function is part of the algorithm name: SHA256withRSA, ECDSA-P256-SHA256, Ed25519 (which has its own internal hash). When you see those strings in a certificate or JWT header, that is the hash-then-sign pattern in action.

04

Sign, Tamper, Verify

The interactive below uses a toy signing function. The math is not real ECDSA, but the protocol behavior is the same: any modification to the message invalidates the signature, and a signature from the wrong key fails verification.

Interactive · Sign and Verify

Sign a message, then watch verification fail when the message is tampered

Type a message, click Sign to produce a signature using Alice's private key. Then edit the message (even one character) and click Verify. The check fails because the signed message no longer matches what is being verified.

No signature yet. Click "Sign" to generate one.
05

RSA Signatures vs ECDSA vs Ed25519

Three signature families dominate the modern landscape. Each has different tradeoffs.

FamilySignature sizeSpeedCaveats
RSA-PSS (2048-bit)256 bytesSlow signing, fast verifyingPadding scheme matters. Old PKCS#1 v1.5 has known attacks.
ECDSA-P25664-72 bytes (DER-encoded)Fast both waysRequires a fresh random k per signature. Reusing k leaks the private key.
Ed2551964 bytesVery fast both waysDeterministic by design. No k-reuse risk. Recommended default.
06

Difference From Encryption

One sentence to internalize: encryption hides content; signatures prove origin and integrity. They are orthogonal. You can have any combination:

07

Where Signatures Live

08

Common Pitfalls

The PlayStation 3 disaster (2010)

Sony signed PS3 firmware with ECDSA-P224. Their implementation reused the same random value k across multiple signatures. With two signatures sharing the same k, an attacker can solve a pair of linear equations and recover the private signing key. The fail0verflow team did exactly that and presented it at 27C3. After that talk, anyone could sign code that would run on a stock PS3. The lesson: ECDSA without per-signature random k is fatal. Ed25519 fixed this by making the equivalent value deterministic from the message and private key, so there is no random source to mishandle.

Verifying without checking the algorithm field

Many JWT libraries had a bug where a token claiming "alg": "none" would be accepted with no signature check. Attackers could forge any token. The library was technically doing what the token asked, which is not the same as doing what the developer intended. Always pin the expected algorithm on the verifier side.