Skip to main content
  1. Blog/

Sharing PGP keys securely using WKD

·2 mins

If you’ve ever tried to use PGP encryption, you’ve likely hit the same wall everyone does: how do you actually get someone’s public key?

The Web of Trust Problem #

PGP’s original solution was the “Web of Trust”, a decentralized model where users verify each other’s identities at key signing parties, creating a network of trust relationships. In theory, if Alice trusts Bob, and Bob verified Carol’s key, Alice can have some confidence in Carol’s key.

In practice, this model failed for several reasons:

  • Scalability: Few people have large circles of crypto-savvy friends willing to attend key signing parties
  • Verification challenges: Recognizing fake IDs is difficult, especially across different countries and alphabets
  • Privacy concerns: Public keyservers expose your email address and reveal your social connections through signatures
  • Complexity: Managing trust levels and understanding signature chains proved too cumbersome for most users

Enter WKD: Web Key Directory #

WKD offers a simpler approach: let domain owners serve their users’ public keys over HTTPS.

When you want to encrypt an email to [email protected], your email client simply fetches her key from example.com using a well-known URL structure. No keyservers, no trust chains, just DNS and TLS providing a basic level of trust that you’re getting a key authorized by the domain owner.

How WKD Works #

WKD defines two URL methods for key discovery:

Advanced Method (preferred):

https://openpgpkey.example.com/.well-known/openpgpkey/example.com/hu/<hash>?l=<localpart>

Direct Method (fallback):

https://example.com/.well-known/openpgpkey/hu/<hash>?l=<localpart>

The <hash> is a z-base-32 encoded SHA-1 hash of the lowercase local part of the email address. Clients try the advanced method first (using the openpgpkey subdomain), then fall back to the direct method.

You also need an empty policy file at the appropriate location, it’s required by the spec even for static hosting.

The Security Model #

WKD provides domain-level trust rather than individual trust. If you trust that example.com belongs to the organization you think it does (via TLS certificates), you can reasonably trust they’re serving the correct keys for their users. It’s not perfect, but it’s practical, and it works automatically in supporting email clients like Thunderbird, KMail, and others.

Hosting Your Own WKD #

Setting up WKD requires generating the correctly hashed filenames and directory structure. Ideally you would use something called WKS (Web Key Service) for dynamic key serving. But for individuals or small organizations without dynamic infrastructure, static hosting is a feasible option. To make the static hosting easier, I created a utility with a GitHub action that generates the necessary files for the advanced method and then deploys them to Cloudflare Pages.