PGP + Discord = ??
Table of Contents
- TL;DR
- Introduction
- Just Use Matrix?
- Why PGP?
- Design Goals
- Methodology
- Implementation Notes
TL;DR I built a prototype extension (PGPCord) that lets you send PGP-encrypted messages over Discord by encrypting payloads client-side before they’re posted. It demonstrates a practical way to layer end‑to‑end encryption on top of an untrusted platform. There are important limitations and attack surfaces — this is proof of concept, not a battle-tested privacy product.
Introduction When you want to send truly private messages, you end up choosing between convenience and security. Centralized chat platforms are convenient but they require you to trust the client/server stack. Traditional E2EE messaging (Matrix, Signal, etc.) reduces server trust, but often pushes complexity into key‑exchange and relies heavily on client and server implementations being correct.
Just Use Matrix? Matrix is a great open protocol with first‑class E2EE in many clients, but:
- You still need to trust the client implementation (and, if you run your own server, the server implementation).
- Many people will not adopt a new platform, so you lose the network effect.
- Matrix E2EE can be brittle (key handling, device sync, and trust management introduce complexity). So while Matrix is ideal in many contexts, it’s not a practical migration for everyone you talk to.
Why PGP? PGP has a few pragmatic properties that make it useful as a compatibility layer:
- Keys are user‑generated and exportable. Public keys can be shared freely; private keys remain local.
- No server can decrypt messages if encryption is done correctly client‑side.
- People already know PGP and key distribution practices (web of trust, key servers, posting public key on websites). PGP is not perfect UX, but for an add‑on that encrypts text before it hits Discord, it brings a clear separation of trust: Discord carries ciphertext only.
Design Goals
- Minimal change to user workflow: write a message in Discord as usual, but allow the extension to encrypt it before sending.
- Client-side private key storage: never upload or expose private keys to Discord or external services.
- Shareable public keys: let users publish their public key (profile, blog, keyserver) for others to use.
- Transparent UX: decrypt messages when they appear in the client UI if the recipient has the private key available locally.
Methodology
- Key management:
- Users generate a PGP keypair in the extension or import an existing one.
- The extension stores the private key in the browser’s secure storage (IndexedDB / WebCrypto-wrapped) and exposes the public key for sharing.
- Encrypt before send:
- When composing a message, the extension intercepts the send action, encrypts the plaintext using recipients’ public keys, and posts the ciphertext instead.
- Format the ciphertext in a detectable wrapper (PGP ASCII armored block, optionally with a small header to help the extension detect it later).
- Detect and decrypt:
- When the client receives messages (including messages from other users), the extension scans for armored blocks, attempts decryption with local private keys, and replaces the ciphertext inline with the decrypted text in the UI.
- Fallback:
- If a recipient lacks a public key in their local address book, fall back to the plaintext send (or warn).
- Provide a way to send a “public key request” message to a user.