← Back to blogWe open-sourced PGP Tools - a browser extension that does PGP properly
/James Arnott

We open-sourced PGP Tools - a browser extension that does PGP properly

Most PGP browser extensions are closed source, have bad UX and just don't manage your keys safely and conveniently. Why would you trust a random "encryption tool" that has access to every site you visit? When we searched for tools we'd be happy using, there were no good extension-based tools we wanted to use and we didn't want to have to keep reverting to the terminal to send a quick message.

PGP Tools is a free, open-source Chrome extension for PGP encryption, decryption, and signing. The entire source is on GitHub under the MIT licence.

Why another PGP extension?

The short answer: we wanted one we could actually trust.

The crypto engine is written in Rust using Sequoia-PGP and compiled to WebAssembly. Your private keys live in WASM linear memory, not on the JavaScript heap. When keys are dropped, they're zeroized deterministically - no waiting for garbage collection to maybe clean things up eventually.

Each private key is encrypted at rest with AES-256-GCM, using Additional Authenticated Data bound to the key's fingerprint. Swapping encrypted blobs between key slots fails. We're the first to use Passkeys with WebAuthn PRF to encrypt the contents, so you don't even have to remember anything. Passwords, if chosen over Passkeys, are derived with Argon2id with 64 MB, 3 iterations, unlike any other extension.

Passkey unlock

This is the single biggest convenience and security improvement over the competition. Instead of typing a password every time you want to decrypt something, you can protect your keys with a passkey - Touch ID, Face ID, Windows Hello, or a YubiKey.

Under the hood it uses WebAuthn PRF to derive a key, combined with a stored secret via HKDF-SHA256.

What it does

  • ECC (Cv25519) or RSA-4096 key generation
  • Encrypt with optional signing
  • Decrypt with automatic signature verification (atomic - bad signature means no plaintext returned)
  • Cleartext sign and verify
  • Import/export armored keys
  • Right-click context menu on selected text
  • Auto-detect and decrypt PGP-encrypted downloads (if enabled)
  • Auto-lock on inactivity, panel close, or per-operation

The UX

The whole thing runs in the browser's side panel, so it stays open alongside whatever you're working on. This also means no other extension can access it.

The main workspace is built around a single input area. Pick an operation from the dropdown, paste text or drag and drop files, select a key, and hit go. If you're using a passkey, the extension prompts your authenticator inline - there's no separate unlock step to break your flow. Password users get a single inline prompt.

It auto-detects what you give it. Paste a public key block and it nudges you to import it as a contact. We also have an optional auto detect feature for downloads, although this requires extra permissions. Download a .pgp file and the extension can auto-decrypt it in the background. Download an .asc public key and it offers to import it.

Right-click selected text on any page and you get encrypt/decrypt/sign/verify in the context menu.

Everything is designed to require as few clicks and thought as possible, whilst remaining secure.

Security

Beyond the zeroing and WASM infrastructure with SequoiaPGP, whenever you close the side panel, the keys are cleared and there's an interaction timeout too. We store everything encrypted, contacts and private + public keys are never stored unencrypted at rest. This means if your Google account gets hacked or your device gets stolen, nothing is freely available, not even your contacts can be read or changed.

We believe cryptography should be convenient, and if it isn't, it's not going to be used where it should be.

One more thing

As with all of our extensions, we took the time to brute force an ID to make it easier to find. This one has: pgp...pgp

pgpcdgggohpbombhkffjoiiafdlfcpgp

Try it out

If you find a bug or have a feature request, open an issue on GitHub.