ellipticc
Overview
How to Use PGP: A Complete Guide to Pretty Good Privacy

What PGP Actually Is (In Plain Language)

Pretty Good Privacy (PGP) is a program that lets you encrypt emails and files so only the intended recipient can read them. Created by Phil Zimmermann in 1991, PGP was revolutionary because it brought military-grade encryption to civilians.

At its core, PGP uses a concept called asymmetric cryptography - you have two keys: a public key that anyone can see, and a private key that only you have. The public key encrypts messages, but only the private key can decrypt them.

Keypairs: Your Digital Identity

Every PGP user has a keypair:

  • Public key: Shared with others, used to encrypt messages to you
  • Private key: Secret, used to decrypt messages and sign documents

Setting Up PGP/GPG

Before creating your keypair, you need to install PGP software. GPG (GNU Privacy Guard) is the most common free implementation of PGP.

Windows Installation

Option 1: Gpg4win (Recommended GUI)

Option 2: Command Line Only

macOS Installation

Option 1: GPG Suite (Recommended)

  • Download from: https://gpgtools.org/
  • Includes MacGPG and GPG Keychain Access
  • Provides system integration

Option 2: Homebrew

Terminal window
brew install gnupg
brew install pinentry-mac # For passphrase prompts

Option 3: MacPorts

Terminal window
sudo port install gnupg2

Linux Installation

Ubuntu/Debian:

Terminal window
sudo apt update
sudo apt install gnupg2

Fedora/CentOS/RHEL:

Terminal window
sudo dnf install gnupg2 # Fedora
sudo yum install gnupg2 # CentOS/RHEL

Arch Linux:

Terminal window
sudo pacman -S gnupg

Verification:

Terminal window
gpg --version
# Should show GnuPG version 2.2.x or later
Tip

GPG comes pre-installed on most Linux distributions. On Windows and macOS, use the official installers for the best experience.

Creating Your First PGP Keypair

Before you can encrypt or sign anything, you need to create your own keypair. This process generates your public and private keys.

CLI Method (GPG - Most Common)

Terminal window
# Generate a new keypair (interactive)
gpg --full-generate-key
# Or use batch mode for automation
gpg --batch --generate-key keygen.txt
Important

After generating your keypair, create a revocation certificate right away and store it offline:

Terminal window
gpg --output revoke.asc --gen-revoke 0xYOUR_KEYID

Store revoke.asc in an encrypted, offline location.

When prompted, choose:

  • Key type: RSA (choose RSA)
  • Key size: 4096 bits (for better security)
  • Expiration: 2 years (set an expiration to force renewal)
  • Name: Your full name
  • Email: Your email address
  • Comment: Optional description

GPG RSA key generation (Linux)

Viewing and Exporting Your Keys (CLI)

After generating a keypair, verify your keys are present and find your key ID.

Terminal window
# List public keys
gpg --list-keys
# List secret/private keys
gpg --list-secret-keys

Example gpg --list-secret-keys output (truncated):

/home/ilias/.gnupg/pubring.kbx
------------------------------
sec rsa4096/0xABCDEF1234567890 2025-12-02 [SC] [expires: 2027-12-02]
FINGERPRINT 0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567
uid Ilias <[email protected]>
ssb rsa4096/0x1234567890ABCDEF 2025-12-02 [E] [expires: 2027-12-02]

Use your key ID (e.g., 0xABCDEF1234567890) or the long hex fingerprint to export keys.

Terminal window
# Export your public key (ASCII armored)
gpg --armor --export 0xABCDEF1234567890
Terminal window
# Concrete example (truncated) showing a real-looking export on Linux
Version: GnuPG v2
mQINBGkvQiMBEADLMPbhKhu63xcHbBxNfJIjIABaxBQ4sIo+yyqkuguufh2Bj9tK
UpFdE3L2jrA2u14vdzHF5OgoTPpuok1hyNXhlWMmLQk8u272nvVJwz9ygFjPd/tG
JCMVtbvGHhhvTccEspvpqB2i+g6Ez+779NWbh4NnLyF5ZqQK9Oru/NfAbpsj3c+n
... (truncated for brevity) ...
=PO11
root@debian:~# gpg --armor --export 0104113A9A5572E65A154606A8E838BEC1246607
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2
mQINBGkvQiMBEADLMPbhKhu63xcHbBxNfJIjIABaxBQ4sIo+yyqkuguufh2Bj9tK
UpFdE3L2jrA2u14vdzHF5OgoTPpuok1hyNXhlWMmLQk8u272nvVJwz9ygFjPd/tG
JCMVtbvGHhhvTccEspvpqB2i+g6Ez+779NWbh4NnLyF5ZqQK9Oru/NfAbpsj3c+n
XjFG+Pv9lO0S5nyOq/4OdcmWgCuRHmoVxzL8Zn14icy6yilnZDNHciDo7KBJ/umP
e3xw78QuB6DQQxAn/ZaBG3g+MH5nk96vM9hn3vMUkQyl81DuY5oWdmyfze0W5sK9
btC5OfNlpG6NxCHE/v3JLBrt9GFvMVqE1YpLizokMfZ3T290hsYVMTW0vpVnbc78
... (truncated for brevity) ...
=PO11
-----END PGP PUBLIC KEY BLOCK-----
Terminal window
# Export your private key (ASCII armored) - DO NOT SHARE
gpg --armor --export-secret-keys 0xABCDEF1234567890
Terminal window
# Concrete example (truncated) showing a secret key export (illustrative only)
Version: GnuPG v2
lQdGBGkvQiMBEADLMPbhKhu63xcHbBxNfJIjIABaxBQ4sIo+yyqkuguufh2Bj9tK
UpFdE3L2jrA2u14vdzHF5OgoTPpuok1hyNXhlWMmLQk8u272nvVJwz9ygFjPd/tG
... (truncated for safety) ...
=YflE
root@debian:~# gpg --armor --export-secret-keys 0104113A9A5572E65A154606A8E838BEC1246607
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v2
lQdGBGkvQiMBEADLMPbhKhu63xcHbBxNfJIjIABaxBQ4sIo+yyqkuguufh2Bj9tK
UpFdE3L2jrA2u14vdzHF5OgoTPpuok1hyNXhlWMmLQk8u272nvVJwz9ygFjPd/tG
JCMVtbvGHhhvTccEspvpqB2i+g6Ez+779NWbh4NnLyF5ZqQK9Oru/NfAbpsj3c+n
XjFG+Pv9lO0S5nyOq/4OdcmWgCuRHmoVxzL8Zn14icy6yilnZDNHciDo7KBJ/umP
e3xw78QuB6DQQxAn/ZaBG3g+MH5nk96vM9hn3vMUkQyl81DuY5oWdmyfze0W5sK9
... (truncated for safety) ...
=YflE
-----END PGP PRIVATE KEY BLOCK-----
root@debian:~#
Warning

Never share your private key. The private key shown above is heavily truncated and for illustration only. Do not post or distribute a real private key online.

Terminal window
# Export to files instead of printing to stdout
gpg --armor --export 0xABCDEF1234567890 > public_key.asc
gpg --armor --export-secret-keys 0xABCDEF1234567890 > private_key.asc
Important

Never upload or share your private key. Store private key backups securely and encrypted (offline USB, password manager, or encrypted vault).

GUI Method (Kleopatra on Windows/Linux, GPG Suite on macOS)

  1. Install GPG4Win (Windows) or GPG Suite (macOS)
  2. Open Kleopatra (Windows) or GPG Keychain (macOS)
  3. Click “New Key Pair” or “Generate”
  4. Fill in your details:
    • Name: Your full name
    • Email: Your primary email
    • Advanced options: Choose RSA 4096-bit
  5. Set a strong passphrase (required!)

Exporting Your Public Key

Once created, share your public key so others can encrypt messages to you:

Terminal window
# Export your public key to a file
gpg --export --armor [email protected] > public_key.asc
# Or export to clipboard
gpg --export --armor [email protected] | clip # Windows (cmd)
# or (PowerShell)
gpg --export --armor [email protected] | Set-Clipboard # PowerShell
gpg --export --armor [email protected] | pbcopy # macOS

Verifying Your Keypair

Terminal window
# List your keys
gpg --list-keys
# Check key details
gpg --keyid-format long --list-keys
Tip

Always backup your private key! Store it securely offline. Losing your private key means losing access to all encrypted messages sent to you.

Importing & Listing Keys: Examples & Troubleshooting

Tip

This section shows real CLI commands and sample outputs. Please verify you have a recent version of GnuPG (2.2+ recommended) to use --quick-add-key and certain smart-card features. If you’re using an older GnuPG version, use gpg --edit-keyaddkey to create subkeys and gpg --gen-revoke to create a revocation certificate interactively.

These commands show realistic outputs for importing keys and list common errors with quick resolutions.

Import a public key

Terminal window
gpg --import alice-public.asc

Sample output:

gpg: key 0x1234ABCD1234ABCD: public key "Alice Example <[email protected]>" imported
gpg: Total number processed: 1
gpg: imported: 1

Import a secret key

Terminal window
gpg --import alice-secret.asc

Sample output:

gpg: key 0x1234ABCD1234ABCD: secret key imported
gpg: Total number processed: 1
gpg: secret keys read: 1

Show key details and fingerprint

Terminal window
gpg --fingerprint 0xYOUR_KEYID
gpg --show-keys alice-public.asc

Sample output:

pub rsa4096/0xABCDEF1234567890 2025-12-02 [SC] [expires: 2027-12-02]
Key fingerprint = 0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567
uid [ultimate] Alice Example <[email protected]>

Common errors and remedies

  • “Can’t check signature: No public key”: Import the signer’s public key or use gpg --recv-keys 0xSIGNER_KEYID.
  • “decryption failed: No secret key”: Ensure you have the correct secret key imported using gpg --list-secret-keys.
  • “BAD signature”: The file might be modified OR you have the wrong public key; verify the fingerprint OOB.

Out-of-band (OOB) Fingerprint Verification & FAQ

Tip

Verify a key’s full fingerprint using an out-of-band channel (phone call, in-person, or other trusted method) to avoid accepting a spoofed key.

For real trust, always verify a key’s full fingerprint through an independent channel.

How to verify a fingerprint OOB

  1. Ask the person to send or read the full fingerprint via phone, video call, or in-person.
  2. Run locally:
Terminal window
gpg --fingerprint 0xTHEIR_KEYID
  1. Compare the full fingerprint; if they match, the key is probably genuine.

Frequently Asked Questions

  • Q: “Why do I get BAD signature?”: A: You probably don’t have the signer’s correct public key or the message was altered. Verify the fingerprint and re-import the correct key.

  • Q: “Why does gpg --verify say unknown signature?”: A: The signature is from a key you don’t trust or have not fully validated.

  • Q: “How do I revoke a compromised key?”: A: Use your pre-generated revoke.asc certificate and publish the revocation to a keyserver or hosting so others can see the revocation.

  • Q: “How do I change my key’s passphrase?”: A: Use gpg --edit-key then passwd in the interactive prompt, then save.

Terminal window
gpg --edit-key 0xYOUR_KEYID
# In the interactive prompt:
# > passwd (change passphrase for the selected key)
# > save
  • Q: “How do I remove a key from my local keyring?”: A: Use gpg --delete-key KEYID for public keys and gpg --delete-secret-key KEYID for secret keys (careful, this removes them locally only):
Terminal window
gpg --delete-secret-key 0xYOUR_KEYID
gpg --delete-key 0xYOUR_KEYID
  • Q: “How do I indicate I trust a key on my machine (ownertrust) or sign someone’s key?”: A: Use gpg --edit-key to set ownertrust or locally sign a key. Example:
Terminal window
gpg --edit-key 0xTHEIR_KEYID
# In the prompt, run: 'trust' to set ownertrust or 'sign'/'lsign' to sign locally
# 'lsign' will create a local-only signature that doesn't get uploaded to keyservers
quit

Identity Binding: Proving Who You Are

PGP binds your identity to your keypair through digital signatures. When you sign a message, anyone with your public key can verify it came from you and hasn’t been tampered with.

What People Get Wrong About PGP

PGP isn’t just for emails - it’s a toolkit for encryption, signing, and authentication. Many think PGP is “email encryption,” but it’s actually a broader cryptographic framework that powers many security tools.

Important

PGP is a standard, not a single program. GPG (GNU Privacy Guard) is the most common free implementation.

How Key Generation Works (Without Math Wizardry)

Generating PGP keys is your first step. Modern tools make this straightforward, but understanding the process helps you make good choices.

Public Key vs Private Key

Your public key is what you share. It’s mathematically linked to your private key, but you can’t derive one from the other. This “trapdoor function” is what makes asymmetric crypto work.

Why Key Length Matters

Key length determines security:

  • RSA 2048: Minimum acceptable today, vulnerable to quantum attacks
  • RSA 4096: Better, but still not quantum-safe
  • ECC (Elliptic Curve): More secure with smaller keys, but some curves are suspect

Why Revocation Is a Nightmare

If your private key gets compromised, you need to revoke your public key. This creates a revocation certificate that you must distribute to everyone who has your key. In practice, revocation rarely works because:

  1. People don’t check for revocations
  2. Keyservers don’t always propagate them
  3. Old keys linger in caches and backups
Warning

Once a key is compromised, revocation is like trying to unring a bell. Everyone needs the revocation certificate before they use your key again.

Revocation: Generate & Publish a Revocation Certificate (Beginner)

A revocation certificate lets you permanently mark your public key as invalid if you lose your private key or it becomes compromised. It’s crucial to create one as a precaution and store it safely offline.

Create & store a revocation certificate

Terminal window
# Create a revocation certificate (recommended: do this on an offline/secure machine)
gpg --output revoke.asc --gen-revoke 0xYOUR_KEYID

Example interactive flow (truncated):

gpg: Please select the key to be revoked:
sec rsa4096/0x1234ABCD1234ABCD 2024-01-01 Alice Example <[email protected]>
Please select the reason for the revocation:
0 = No reason specified
1 = Key has been compromised
2 = Key is superseded
3 = Key is no longer used
Enter the number corresponding to the reason: 1
Enter an optional description; end with an empty line:
Key material compromised 2025-12-02
Really revoke this key? (y/N) y
Revocation certificate created and saved as 'revoke.asc'.

Import & verify locally (optional)

Terminal window
gpg --import revoke.asc

Expected output:

gpg: key 0x1234ABCD1234ABCD: revocation certificate imported
gpg: Total number processed: 1
gpg: revocations: 1

Publish the revocation (so others see it)

Option A: Publish to a modern keyserver

Terminal window
gpg --keyserver hkps://keys.openpgp.org --send-keys 0xYOUR_KEYID

Option B: Upload the revocation to your hosting or a public web path and notify contacts

Verify revocation is visible:

Terminal window
gpg --keyserver hkps://keys.openpgp.org --recv-keys 0xYOUR_KEYID
gpg --list-keys 0xYOUR_KEYID
# Look for a [revoked: DATE] marker on the UID in the list
Warning

Generate your revocation certificate on a secure machine and store it in an encrypted, offline location (different from where you store secret key backups). Do not keep your revoke.asc with the active private key backups.

How to Encrypt a Message With PGP

Encrypting with PGP requires the recipient’s public key. Here’s how it works in practice.

CLI Method (GPG)

Terminal window
# Encrypt a file for someone
gpg --encrypt --recipient "[email protected]" message.txt
# This creates message.txt.gpg

GUI Method (Kleopatra, GPG4Win)

  1. Right-click file → “Sign and Encrypt”
  2. Select recipient’s certificate
  3. Choose encryption algorithm (AES-256 recommended)
  4. Send the .gpg file

Example Commands

Terminal window
# Encrypt and sign a message
gpg --encrypt --sign --recipient [email protected] letter.txt
# Sample output (truncated)
root@debian:~# gpg --encrypt --sign --recipient [email protected] letter.txt
gpg: encrypting for [email protected]
# The resulting file `letter.txt.gpg` is created
# Decrypt a message
gpg --decrypt encrypted.txt.gpg > decrypted.txt
# List your keys
gpg --list-keys

Example gpg --list-keys output (truncated):

pub rsa4096/0xABCDEF1234567890 2025-12-02 [SC] [expires: 2027-12-02]
FINGERPRINT 0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567
uid Ilias <[email protected]>
sub rsa4096/0x1234567890ABCDEF 2025-12-02 [E] [expires: 2027-12-02]

Example gpg --decrypt output (truncated):

root@debian:~# gpg --decrypt encrypted.txt.gpg > decrypted.txt
gpg: encrypted with RSA key, ID 0x1234567890ABCDEF
gpg: decryption OK
root@debian:~# cat decrypted.txt
Hello Bob,
This is a secret message.

Sample gpg --decrypt failure case (no secret key):

root@debian:~# gpg --decrypt encrypted.txt.gpg > decrypted.txt
gpg: encrypted with RSA key, ID 0x1234567890ABCDEF
gpg: decryption failed: No secret key

Typical Mistakes

  • Wrong user IDs: Using an old email address
  • Expired keys: Keys have expiration dates
  • No trust path: PGP requires building trust networks
  • Weak algorithms: Using outdated ciphers like 3DES

How to Digitally Sign a Message

Signing proves authenticity and integrity - it shows the message came from you and hasn’t been changed.

Signature ≠ Encryption

Signing is different from encryption:

  • Signing: Anyone can read, but they know it’s authentic
  • Encryption: Only you can read, but authenticity isn’t guaranteed

Verifying Signatures

Terminal window
# Verify a signed file
gpg --verify signed.txt.gpg
# Output shows signer and whether signature is valid

Example gpg --verify output (truncated):

gpg: Signature made Fri 02 Dec 2025 12:34:56 PM UTC
gpg: using RSA key 0xABCDEF1234567890
gpg: Good signature from "Ilias <[email protected]>" [ultimate]

Example gpg --verify output for a detached signature (truncated):

root@debian:~# gpg --verify message.txt.sig message.txt
gpg: Signature made Fri 02 Dec 2025 12:34:56 PM UTC
gpg: using RSA key 0xABCDEF1234567890
gpg: Good signature from "Ilias <[email protected]>" [ultimate]

Sample gpg --verify failure cases:

# BAD signature (message was altered or signature doesn't match key)
gpg: Signature made Fri 02 Dec 2025 12:34:56 PM UTC
gpg: using RSA key 0xABCDEF1234567890
gpg: BAD signature from "Ilias <[email protected]>" [unknown]
# Or: public key not found (can't verify without the signer's public key)
gpg: Can't check signature: No public key

Creating Signatures (Examples & Output)

Terminal window
# Create a binary signed file (not human-readable)
gpg --sign -o message.txt.gpg message.txt
# Create a detached signature (good for sending alongside the file)
gpg --detach-sign -o message.txt.sig message.txt
# Create a cleartext-signed file (readable message with ASCII signature)
gpg --clearsign message.txt

Sample gpg --clearsign output (truncated but longer for clarity):

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hello Bob,
This is a clear-signed message example. Please verify the signature that follows.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
mQINBGP0oQMBEADLMPbhKhu63xcHbBxNfJIjIABaxBQ4sIo+yyqkuguufh2Bj9tK
UpFdE3L2jrA2u14vdzHF5OgoTPpuok1hyNXhlWMmLQk8u272nvVJwz9ygFjPd/tG
VGhtc3Ryb25nQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo0NTY3ODkw
YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXphMTIzNDU2Nzg5MA==
=QW3V
-----END PGP SIGNATURE-----

Sample gpg --detach-sign output (no stdout, but file created):

root@debian:~# gpg --detach-sign -o message.txt.sig message.txt
# The detached signature `message.txt.sig` is created

Sample gpg --sign output (signed file created):

root@debian:~# gpg --sign -o message.txt.gpg message.txt
# The signed file `message.txt.gpg` is created

What Signing Actually Protects Against

Digital signatures protect against:

  • Tampering: Content changes invalidate the signature
  • Impersonation: Only your private key can create valid signatures
  • Repudiation: You can’t deny sending a signed message

How to Share Your Public Key Safely

Sharing public keys securely is crucial - a fake key lets attackers read your encrypted messages.

Keyservers

Keyservers are public directories where you upload your public key:

Terminal window
# Upload your key
gpg --send-keys your-key-id
# Search for someone's key
gpg --search-keys "[email protected]"

Further reading & background (SKS keyserver issues)

The SKS keyserver pool, historically the default for many OpenPGP clients, suffered operational, privacy, and abuse problems (spam, fake identities, and “poisoning” of keys). A few good resources:

Note

If keyserver commands fail, make sure dirmngr is installed and running (it handles HTTP/HTTPS access for GPG). On Debian/Ubuntu you can install it with sudo apt install dirmngr, and restart with gpgconf --reload dirmngr or gpgconf --launch dirmngr.

Subkeys, Rotation, and Basic Practices

Tip

Use a primary, offline key for certification and subkeys for daily use. Rotate subkeys periodically and keep backups of necessary material.

Subkeys let you keep a primary (certification) key offline and use subordinate keys for day-to-day signing and encryption. This is a widely recommended practice to limit exposure.

  • Create a primary key for certification and store it offline.
  • Create subkeys for signing and encryption that live on your regular device.
  • Rotate subkeys periodically (e.g., annually or whenever suspected compromise). Use revocations for compromised subkeys.
  • Create and keep a revoke.asc for the entire key (and possibly a dedicated one for subkeys).

Create a key with subkeys (examples)

Terminal window
# Interactive method: create a primary key and add subkeys during setup
gpg --expert --full-generate-key
# Choose a primary key (e.g., RSA 4096) for certification only, or Ed25519 for modern use
# During the interactive UI add separate subkeys for signing and encryption
Terminal window
# Non-interactive quick add (modern GPG)
# Add an Ed25519 signing subkey that expires in 1 year
gpg --quick-add-key 0xYOUR_KEYID ed25519 sign 1y
# Add an X25519 encryption subkey that expires in 1 year
gpg --quick-add-key 0xYOUR_KEYID x25519 encrypt 1y

Backup & rotation

  • Keep backups of ~/.gnupg or exported keys encrypted and split across secure storage.
  • When rotating subkeys, generate a new subkey, move operations to the new subkey, and revoke the old subkey.
  • When rotating the primary key, make a clear plan: create key, create revocation for the old one, distribute new public key and verify OOB.

Advanced safety: To avoid exporting your primary/master key, consider exporting only secret subkeys for day-to-day backups:

Terminal window
# Export only secret subkeys (avoids including the primary/master key)
gpg --export-secret-subkeys --armor 0xYOUR_KEYID > subkeys-backup.asc

Checks & Debugging

Terminal window
# Check signatures on a key (helpful to inspect signature chain)
gpg --check-sigs 0xTHEIR_KEYID
# Check low level packet details (advanced debugging)
gpg --list-packets <file>

If you want, I can add an explicit step-by-step example for key generation with a primary key and two subkeys (with command snippets) and a short key rotation workflow.

Backup, Expiration & Hardware Tokens

Important

Hardware tokens (YubiKey, Nitrokey) improve safety by keeping keys offline. Back up secrets encrypted and keep expiration and rotation policies documented.

Backups

Create encrypted backups of your private keys (do not store them on public cloud storage unencrypted):

Terminal window
# Export private keys to an armored file (never share this)
gpg --armor --export-secret-keys 0xYOUR_KEYID > private-backup.asc
# Encrypt the backup file with symmetric encryption for safe cloud storage (writes .gpg)
gpg --symmetric --cipher-algo AES256 --output private-backup.asc.gpg private-backup.asc

Restoring

Terminal window
# Import your private key backup
gpg --import private-backup.asc

Setting/Extending expiration

Terminal window
gpg --edit-key 0xYOUR_KEYID
# In the interactive `gpg` session:
# > expire
# > select expiration (e.g., 2y)
# > save

Hardware tokens (optional hardening)

Hardware tokens (YubiKeys, Nitrokeys) provide strong protection by keeping your private keys on a dedicated device.

Terminal window
# Check for an attached smart card/YubiKey
gpg --card-status
Tip

When using hardware tokens, generate or store subkeys on the token and keep the primary key offline. Use subkeys for day-to-day signing and encryption.

These resources explain the history, abuse patterns, and motivations for modern services like keys.openpgp.org and WKD (Web Key Directory).

Retrieving & Verifying Keys Securely (keys.openpgp.org examples)

Use the keys.openpgp.org REST API or gpg’s built-in retrieval methods. Always verify the fingerprint OOB (in person, or over a trusted channel) before trusting a key.

Terminal window
# Download a key for an email address (keys.openpgp.org API)
curl -s "https://keys.openpgp.org/vks/v1/[email protected]" -o alice.asc || echo "no key found"
# Preview the key (shows UIDs and fingerprint)
gpg --show-keys alice.asc
# Optionally import the key after verifying the fingerprint out-of-band (phone/in-person)
gpg --import alice.asc
# Retrieve a key by fingerprint (if you already have the fingerprint)
curl -s "https://keys.openpgp.org/vks/v1/by-fingerprint/0123456789ABCDEF0123456789ABCDEF01234567" -o key.asc
gpg --show-keys key.asc
gpg --import key.asc
# Confirm the fingerprint locally
gpg --fingerprint 0xABCDEF1234567890

Note: keys.openpgp.org restricts identity publication (email/userids) to verified addresses; this step reduces the risk of a malicious third-party publishing fake identity information.

Fingerprints

Every key has a unique fingerprint - a short string that identifies it uniquely. Always verify fingerprints in person or over a trusted channel:

Terminal window
# Show your key fingerprint
gpg --fingerprint [email protected]

What People Mess Up

  • Not verifying fingerprints: Trusting keys from unverified sources
  • Using HTTP keyservers: No encryption in transit
  • Ignoring key expiration: Using old, potentially compromised keys

MITM Issues

Man-in-the-middle attacks happen when someone substitutes their key for yours. This is why fingerprint verification is critical.

How MITM Works in PGP:

  1. Alice wants Bob’s public key
  2. Mallory (attacker) intercepts the request
  3. Mallory sends her own public key instead of Bob’s
  4. Alice encrypts messages with Mallory’s key (thinking it’s Bob’s)
  5. Mallory can read all messages and re-encrypt them for Bob

Real-World Example: The traditional SKS keyserver network suffered abuse and “poisoning” (spam and malicious data appended to keys) and privacy issues. This led to a community effort to build safer key discovery services such as keys.openpgp.org, which changes how identity information is published and requires verification. See keyserver discussions and archives (e.g., SKS issues on OSS-Security) and the keys.openpgp.org project for background.

Why This Matters: Unlike HTTPS certificates (which have Certificate Authorities), PGP has no central authority. Trust is entirely manual.

Trust Chains

PGP uses a web of trust where you sign others’ keys to build trust networks. In practice, most people skip this and just exchange keys directly.

How Web of Trust Works:

  • You meet someone in person
  • You verify their government ID matches their PGP fingerprint
  • You sign their key with your private key
  • Others can see your signature as a “trust endorsement”
  • Trust propagates: “Alice trusts Bob, and I trust Alice, so I trust Bob”

Why It Failed:

  • Social overhead: Requires meeting people IRL
  • No incentives: Most users don’t participate
  • Scalability issues: Can’t build trust for millions of users
  • Bootstrap problem: How do you trust the first signatures?

Modern Alternative: Keybase tried to solve this with social proof (linking to GitHub/Twitter), but even that service shut down.

Why PGP Is Painful in 2025

Despite its historical importance, PGP has significant problems in modern use.

No Forward Secrecy

Old messages stay readable if your key is compromised. Modern systems rotate keys so compromise only affects recent messages.

PGP’s Problem:

  • You use the same keypair for years
  • If compromised today, ALL historical messages become readable
  • No way to “retroactively secure” old conversations

Modern Solution - Forward Secrecy:

  • Each conversation uses unique ephemeral keys
  • Keys are deleted after use
  • Compromise only affects messages sent during the compromise window

Real Impact: The Snowden leaks showed how NSA could read PGP-encrypted emails from years earlier because the same keys were reused.

Ancient Crypto Primitives

PGP still supports algorithms from the 1990s:

  • RSA: Vulnerable to quantum attacks
  • ElGamal: Slow and complex
  • 3DES: Officially deprecated

Algorithm Timeline:

  • 1991 (PGP 1.0): RSA, IDEA encryption
  • 1997 (PGP 5.0): Added ElGamal, CAST5
  • 2009 (PGP 9.0): Added AES (finally!)
  • 2025: Still supports 3DES from 1970s

Performance Issues:

  • RSA signing is slow (milliseconds per signature)
  • ElGamal encryption is computationally expensive
  • No hardware acceleration support in many cases

Trust Model Is Broken

The web of trust never caught on. Most people don’t verify key fingerprints or build trust networks.

Usage Statistics:

  • Most PGP users never check fingerprints
  • Keyservers contain millions of unverified keys
  • Corporate PGP deployments skip verification entirely
  • Social engineering beats technical security

Consequence: Most PGP “security” is illusory. Users trust keys from email signatures or unverified sources.

Key Revocation Is Unusable

As mentioned, revocation certificates rarely propagate. Compromised keys stay in circulation.

How Revocation Should Work:

  1. Generate revocation certificate when creating keys
  2. Store it safely offline
  3. If key compromised, publish revocation certificate
  4. All systems should check and honor revocations

Reality:

  • Users lose revocation certificates
  • Keyservers don’t always sync revocations
  • Email clients cache keys indefinitely
  • No automatic revocation checking

Famous Example: The Debian SSH key compromise in 2006 showed how revocations fail in practice.

UX Is Prehistoric

Command-line interfaces and complex workflows make PGP inaccessible to normal users.

User Experience Issues:

  • Key management: Remembering key IDs, fingerprints, expiration dates
  • File handling: .asc, .gpg, .sig extensions confuse users
  • Error messages: Cryptic output like “gpg: decryption failed: No secret key”
  • Platform differences: Different tools on Windows/macOS/Linux

Adoption Barrier: PGP requires technical knowledge that most people don’t have and don’t want to learn.

Quantum Attacks Make RSA/ElGamal Obsolete

Shor’s algorithm can break RSA on quantum computers. PGP’s foundation is crumbling.

Quantum Threat Timeline:

  • Current: No large-scale quantum computers exist
  • 2025-2030: Research prototypes emerge
  • 2030-2040: Practical quantum computers arrive
  • 2040+: RSA/ECC broken for all key sizes

PGP’s Quantum Problems:

  • RSA keys need 15,000+ bits for quantum resistance (vs 4096 today)
  • No post-quantum algorithms in PGP until very recently
  • Migration path unclear for existing keys

No Modern Metadata Protection

PGP headers leak information about sender, recipient, and message size. Modern systems hide this metadata.

What PGP Reveals:

  • Sender’s key ID and email
  • Recipient’s key ID and email
  • Message size (can indicate content type)
  • Timestamp of encryption
  • Software version used

Traffic Analysis Attacks:

  • ISPs can see who communicates with whom
  • Message sizes reveal if it’s text, documents, or media
  • Timing patterns show conversation frequency

Modern Solutions: Protocols like Signal pad messages to hide sizes and use sealed sender to hide metadata.

Why Modern E2EE Systems Replaced PGP

Today’s messaging apps use protocols that solve PGP’s problems.

Signal’s Double Ratchet

Signal’s protocol provides:

  • Forward secrecy: Keys rotate after each message
  • Post-compromise security: Compromise doesn’t affect future messages
  • Automatic key exchange: No manual key management

How Double Ratchet Works:

  1. Initial key exchange establishes shared secret
  2. Each message derives new keys from previous message
  3. Old keys are immediately deleted
  4. Compromise only affects current session

Benefits:

  • No long-term key storage needed
  • Perfect forward secrecy built-in
  • Works for both 1:1 and group chats

X3DH / MLS

Messaging Layer Security (MLS) enables:

  • Group encryption: Secure group chats
  • Key transparency: Detects key compromise
  • Asynchronous messaging: Works offline

MLS Features:

  • Tree-based encryption: Efficient for large groups
  • Post-compromise security: Key updates after compromise
  • Forward secrecy: Keys rotate regularly
  • Interoperability: Works across different apps

Key Transparency

Key transparency systems like Google’s Converged Key Transparency provide:

  • Public key logs: Append-only records of all keys
  • Auditable history: Anyone can verify key changes
  • Compromise detection: Users notified of suspicious key changes

How It Works:

  • All public keys logged in tamper-proof ledger
  • Clients check logs for key validity
  • Automated monitoring detects anomalies
  • Users get warnings about key changes

Services like Google’s Key Transparency publish all keys, making substitution attacks detectable.

Short-Lived Keys

Modern systems use ephemeral keys that expire quickly, limiting damage from compromise.

Automatic Rotation

Keys rotate automatically - no manual intervention required.

Forward Secrecy + Post-Compromise Security

These properties ensure that even if keys are compromised, only limited communication is affected.

Tip

PGP was revolutionary in 1991. It’s not sufficient in 2025. Modern encryption needs forward secrecy, quantum safety, metadata protection, and automatic key negotiation.

If PGP Is Legacy Crypto, What Should You Use Instead?

For everyday communication, use apps with modern E2EE:

  • Signal: Best for private messaging
  • Session: Metadata-resistant messaging
  • Element: Decentralized, E2EE by default

For file encryption, consider tools built on modern cryptography rather than PGP’s legacy framework.

PGP taught us that encryption matters. Modern tools make it practical and secure. The future belongs to systems that are both powerful and usable.

Tip

Try Ellipticc Drive →

Because privacy shouldn’t require a PhD in cryptography.

ellipticc.
ellipticc.
ellipticc.
ellipticc.
ellipticc.
ellipticc.