PGP Key Discovery Mechanisms Explained
Table of Contents
Okay, final thing on PGP after talking about PGP itself and Signature and trust levels, we have… How you can get someone else’s public key.
There’s a few common ways to do this:
- Web Key Directory
Let’s discuss how they all work.
PGP Keyservers (HKP Protocol)
This is pretty much the most common form of distributing and sharing keys: using a web keyserver, or keyserver pool, like
The protocol used here is the… HTTP Keyserver Protocol, or HKP (HKPS if over HTTPS).
And by “protocol” I mean “very specific HTTP query strings”.
For example, if I wanted to ask
keys.gnupg.net for the key with this fingerprint:
C1CB 0206 9205 8541 6627 6FD2 998E A222 3673 9B9B
I could use this
Let’s break that down if you don’t see the pattern:
- We send a HTTP request to, by default, port 11371
- The path is always
opparameter specifies the operation, in this case,
getto retrieve a specific key. Others might include
indexto get a list of matching keys, or the like.
searchparameter is the search string we’re using, in this case, it’s the entire key fingerprint, prefixed with
mr, meaning the response to this request should be machine readable.
You will rarely need to interact with this directly, since just about any PGP software on the planet will know how to talk to keyservers, and you’re free to send, search, and receive, using their interface as much as you like. Just note that once your key is in a server, usually, it can’t get fully deleted, so don’t publish keys unless you intend to share them with the world.
Keyservers are nice for people who don’t have authoritative control of the domain in their user ID, like users that have keys with
gmail.com addresses in them.
Web Key Directory Protocol
Here’s a weird, but cool one. WKD, or Web Key Directory, is another method of fetching keys via HTTP, but this one doesn’t have a reliance on external keyservers. WKD works by placing keys in a “well-known” location on a domain’s webserver, allowing HTTP requests to be made to grab a file containing key data.
For a domain, say,
example.com, all requests are to files in
https://example.com/.well-known/openpgpkey/hu/, where the file name is a hash of the user-part of the email address.
For example, the user-ID, and, thus, email address,
[email protected] would translate to looking up:
There are a few other requirements though:
Access-Control-Allow-Originheader mush be present for this resource, and have a value of “
- A policy file at
/.well-known/openpgpkey/policymust exist, but, since it has no useful information right now, is just an empty file.
- The file much contain the binary (not ASCII-armored) representation of the key block
A companion service called WKS exists to automatically manage keys in your WKD, but we won’t cover that right now.
Additionally, there is an “advanced” lookup method, that prepends
openpgpkey to the domain name, but otherwise has the same path, meaning that there are two addresses one can fetch a potential key from:
Only if you’re a domain owner of service provider would you likely be able to set up WKD, since it requires access to the webserver of the domain name in your user ID.
Fetching Keys from DNS
This one you have to seriously be a domain owner, because you need to modify the DNS records for the domain in your user ID, which is something that, unless you own said domain, you’re likely not ever going to have access to. But since it does exist, I’ll cover it.
Cert records might not be recognized in whatever DNS manager you’re using, but they do exist as type 37, which most servers, like BIND, will understand by specifying the record type as
Note that… you’re likely not going to write these by hand.
A tool called
make-dns-cert is all you need, which can take in a key file, and a domain name, and spit out a zone file compatible
TYPE37 record which contains…. your entire key.
This is nice because it’s one self-contained thing, but the disadvantage is that means that it’s huge. Any client that doesn’t support EDNS or DNS-over-TCP is just not going to be able to retrieve a data block that large, and like I said before, most servers don’t have support for
CERT records like that.
There is a short mode for
CERT records, which makes them behave more like PKA — If you give
make-dns-cert a URL and a fingerprint instead of a key file, it will make a binary
CERT record that’s much shorter and behaves almost identically to the PKA records that are discussed below.
Using PKA Records
Honestly, this one is the simplest, for people that can do it.
First, you take your email address, say,
_pka to replace the
@, meaning the DNS record will live at
The record is comprised of three fields: the version (which is always
pka1 ), a fingerprint, and a URI where the key can be fetched.
Here’s an example PKA record:
test._pka.example.com TXT "v=pka1;fpr=C1CB02069205854166276FD2998EA22236739B9B;uri=https://example.com/keys/test.pub.txt"
All you’d need to do after that is to actually make the file
test.pub.txt there contain the ascii-armored (read: PEM encoded) public key block for the key specified by that fingerprint.
The advantage of using PKA records is that they’re small — just a fingerprint and a URI, but the disadvantage is that they’re not self-contained, you still need to actually make the file on the webserver that it points to.
These are the weirdest of them all, since there’s almost no documentation, despite being one of two with actual RFCs behind them.
The DNS label for these is weird, where, instead of PKA, which used
user._pka.domain, this uses
hash._openpgpkey.domain, leading to the record for
[email protected] to exist at:
Yes, that’s the hexadecimal representation of the first 28 bytes of the SHA-256 hash of the user part. I don’t even.
Even better, the
OPENPGPKEY format does encode your entire key into binary data in the record, but it doesn’t store everything, the RFC itself defines a lot of fields that should be stripped away to shorten the message size.
if you’re going the DNS route, just use PKA records. They’re just text, human readable, human writable, small, and can be trivially parsed by more than just specific PGP applications. Realistically though, don’t use DNS. Either publish your key to a well-known HKP server, or, if you do own your own mail domain, you can put your key there for WKD, but for 99% of people, keyservers are good enough for everything.