applied · level 4

PGP & Web of Trust

Hybrid encryption, trust paths, why PGP lost.

210 XP

PGP & Web of Trust

PGP — Phil Zimmermann's "Pretty Good Privacy" from 1991 — was the first widely-deployed public-key email encryption tool. Its modern incarnation is OpenPGP (RFC 9580), implemented by GnuPG (gpg) and Sequoia. It still ships on every Linux distribution, still signs every Debian package, and still fails for most users who try to encrypt email with it. Knowing both how PGP works and why it lost is part of being literate in applied cryptography.

Analogy

Imagine a Renaissance-era merchant travelling far from home with a letter of introduction. Rather than rely on a single official seal (which a faraway stranger can't verify), the merchant carries endorsements from a chain of people — her uncle vouches for her, a neighbouring town's abbot vouches for her uncle, and a visiting duke has vouched for the abbot. Anyone who personally trusts the duke, or the abbot, or the uncle, will accept her letter. PGP's web of trust works exactly this way: there is no single official authority, just a social web of signatures where each person you already trust can transitively introduce you to strangers. It is historically charming and, for most modern users, a social logistics nightmare.

What PGP actually does

A PGP message mixes symmetric and asymmetric crypto — the classic hybrid pattern.

  1. Generate a random session key K.
  2. Encrypt the plaintext with a symmetric cipher (usually AES-256-CFB or AES-256-OCB in modern GnuPG) using K.
  3. Encrypt K with the recipient's RSA or ECC public key.
  4. Optionally sign the plaintext's hash with the sender's private key.
  5. Wrap all of the above in the OpenPGP packet format (ASCII-armor if sending via email).

The recipient uses their private key to unwrap K, decrypts the body, and verifies the signature against the sender's public key. This is the same high-level recipe as S/MIME, age, CMS, and roughly everything else in the key-wrapping family.

The web of trust

The genuinely novel idea in PGP was its trust model. Instead of appointing a hierarchy of Certificate Authorities, PGP asked users to sign each other's keys. Meeting someone at a key-signing party, verifying their ID, and signing their key asserts "I've checked this fingerprint belongs to this person".

A key is considered valid to you when it has either:

  • Direct trust — you've signed it yourself, or
  • Introducer trust — one or more keys you've explicitly flagged as trusted introducers have signed it.

GnuPG's configurable marginals-needed and completes-needed tune how strict this is. The default is "one trusted introducer is enough"; in high-security environments you dial it up to require multiple independent signers.

# Sign Alice's key, asserting you've verified it belongs to her:
gpg --lsign-key alice@example.com

# Mark Alice as a trusted introducer:
gpg --edit-key alice@example.com
> trust
> 4    # "I trust fully"

# Now anyone Alice signs is automatically valid for you.

Why PGP lost

Despite being technically correct, PGP was defeated by usability and modern requirements:

  • Keys that are hard to transport. A modern RSA-4096 PGP key is >600 lines of armored text. Fingerprints are 40-hex-char strings. Users share them by email attachment, and then discard them. Compare this to an age recipient (age1abcd...) — one 60-ish-char line you can read over the phone.
  • No forward secrecy. Every message to the same recipient is encrypted to the same long-term key. Steal that key (seize the laptop, subpoena the password) and every email they've ever received becomes decryptable. Signal's double ratchet was the answer to this.
  • Metadata leakage. PGP encrypts bodies, not subject lines, not routing envelopes. Your email provider still sees "from/to/when".
  • Key rotation is a nightmare. You can add a new subkey, but revoking an old one requires distributing a revocation certificate that other people have to remember to import. In practice, nobody rotates.
  • The UX is an afterthought. "Why Johnny Can't Encrypt" (Whitten & Tygar, 1999) documented real users failing at every step. Twenty years later, it's no better. Most PGP-signed emails that land in inboxes are from mailing lists that sign themselves.
  • Signatures attached to trust, not identity. The fact that a signature verifies doesn't mean you should believe it — that's a separate question of whether you trust the signer. This is where beginners go wrong and where sophisticated attackers hide.

What replaced PGP, for what

Need Modern tool
Encrypting a file for someone age — short recipients, ChaCha20-Poly1305, one-line keys
Signing a file minisign or signify — Ed25519, tiny keys
Signing a Git commit Git + OpenSSH signatures (gpg.format = ssh) — same SSH key you already have
Signing a release Sigstore cosign — OIDC-based, publishes to a public transparency log
Encrypting messages to a person Signal — forward secrecy + post-compromise security
Encrypting email There is no good answer. The consensus answer is "don't send sensitive data over email."

Modern code-signing in particular has moved away from the web-of-trust model entirely. Sigstore uses your OIDC identity (GitHub, Google, etc.) as the signing identity, captures the signature in an append-only Rekor transparency log, and verifies against policy (the signer is who they claim, at the time they claim it). It inherits the lessons of Certificate Transparency.

Where PGP is still used

  • Linux distributions — Debian, Ubuntu, Arch sign every package with an OpenPGP key. This isn't going away. The trust path is small and well-known: the distribution's signing key is bundled in the base install.
  • Keybase / Keyoxide — modern web-of-trust UIs that let you attach OpenPGP keys to social-media identities. Useful for the "prove this is me" problem.
  • Forensic and archival signatures — signing a historical document once, in a way that's verifiable 20 years later, is exactly PGP's strong suit: no per-message key derivation, just a signature against a long-term key.

What the playground tests

You'll be shown a signed message's claimed key and your web-of-trust database. Decide: does the verifier produce "good signature from a trusted key", or "good signature from an untrusted key", or "bad signature"? The point is the split — crypto check and trust check are two different decisions, and a good UI must surface both. Every beginner's PGP bug is treating "the signature verified" as equivalent to "the message is trusted".