My Profile Photo

Sheogorath's Blog

Depending on the time of the day a friend, a colleague, a wise guy. The beauty of the world is its sense of humor to show humans their way by letting them search their own.

Cover image for this blog post

Let's discover OpenPGP keys

I don’t know how familiar you are with OpenPGP as a standard or GnuPG as one of the providers for OpenPGP, but it’s one of the two big standards for email encryption. Besides that it’s also used for signing software packages in almost all Linux distributions, signing ISO files to make sure the initial install is correct, and so on.

In other words in the free software world and beyond it’s one of the fundamental tools. But today we want to focus on the most tricky problem that people have when they try to use it for email: Key discovery.

The problem

The trust of a signature depends on the fact that a key is trusted or not. In the world of x509 certificates this is usually solved by trust anchors better known as Certificate Authorities (CA). Those provide so-called CA certificates that are pre-loaded in operating systems, web browsers, etc. and build the root of trust. When you want to be “trusted”, you have to convince one of those CAs to sign your certificate with their CA certificate. Once that is done, you can send your signed public key (also called certificate) to a third party and as long as they trust the CA, they also trust your certificate.

For OpenPGP and GnuPG it’s different. They don’t have this kind of authority structure. Here the root of trust is you. You decide what public keys you download and trust. In some cases, like your linux distribution, this trust is already pre-configured i.e. with the GnuPG keys of your linux distribution.

For email you have to find the right keys for your correspondence yourself. And there are 3 traditional ways to get those.

By email

That’s the simplest and functional way. When you send out an email to someone for the first time, simply attach your public key. The recipient can then import this key and send their public key back to you and already use an encrypted email for that.

Main problem: How do you know that the your mail provider or the recipient’s doesn’t exchange the key with an own one and then de-crypts all messages, and re-encrypts with a different key? Not to mention possible eavesdroppers that do that, due to email’s nature of being not secure in general. Those are classic man-in-the-middle-attacks.

By keyserver

Another way to exchange keys, especially for people you never talked to before, is the usage of keyservers. There are hundreds of keyservers out there and the basic idea is that you upload your public key to a keyserver and people can find it based on the email address.

There are different kinds of keyservers; some allow everyone to upload whatever key they want, other are more strict and require an authentication before you can upload a key, finally there are some that only allow keys that are generated by the keyserver’s owner.

Anyway, the major problem all of them have: How do you know on which keyserver the key is? And how to you know that the key that is on this keyserver was uploaded by the owner of that email address?

By the web of trust

The web of trust is a fundamental concept in OpenPGP. The idea is that know people. Like your friends, your family, business partners, ….

Whenever you meet one of those, you check their keys and sign them with yours. Because you can verify that this is for sure their key and everyone can see that you signed this key.

The idea is to build a topology of trust with your key as center. You trust your friend’s key. And every key your friend’s key trusts is also somehow trusted by you. Everything that your friend’s friend’s key signs, is no longer trusted. It’s an idea that based on how people meet each other in private life. Often you just happen to hang out with someone you know and meet someone new, that the person you hang out with knows.

But somehow this often doesn’t work out. You have to visit so-called crypto-parties and people around you have to use OpenPGP. Reality shows that this simply is not the case for most people out there. And you still have no way to know whose key it is when you have no such relationship to the key owner.

The solution

With all this said, you may go back to the file approach: “I just upload it to my website that is provided over HTTPS and everyone can download my key there. Everyone knows it’s my website, so they know they got the right key.”

And that’s basically the idea behind the Web Key Directory (WKD). Just that you don’t throw the file anywhere on your website, but in a specific location.

How to set up

I’ll just explain a bit how I set up WKD for my own blog. For static page generators is rather easy to set up, for websites running WordPress or Drupal, you can put it directly on your webserver. In case of Ghost or other CMS systems that run behind a reverse proxy, you may consider to put your key on this reverse proxy.

But back to the setup, first of all you should create the directories .well-known/openpgpkey and .well-known/openpgpkey/hu that are used for the discovery.

Now place a policy file at .well-known/openpgpkey/policy. This describes how one would submit a key to your key directory. Since it’s your website/domain you only want your own key there. So the file would look like this:


Correction: Use an empty policy file. But this empty file is required as some service providers use it to discover WKD availability.

mailbox-only tells the client that only keys that have a mailbox on this domain are allowed to submit their keys. Correction: tells the client that only key are accepted that use the address only. Larger email providers could use such a policy to make clear that they only accept customer keys. All possible flags can be found in the draft of the standard.

All that is left to do is copying your key into the right place.

You need to find your email addresses’ hash by running gpg --with-wkd-hash --fingerprint --keyid-format 0xlong <mail address>. You’ll find a line that looks like an email address but has a hash in front of it. (e.g. for my email address).

The hash is the name of the file where you’ll place your key. You can now run gpg --no-armor --export 0x<keyid> > <hash>. Replace <keyid> with the id of your public key, that you could also see in the previous output (it starts with 0x<something>) and of course <hash> with the hash from the mail address.

Now copy this file into .well-known/openpgpkey/hu and you are ready to be discovered.

To make sure you are standard compliant, you should set the correct MIME-type for your WKD.

You should add the following snippet to your nginx configuration for your vhost:

location /.well-known/openpgpkeys/hu/ {
  default_type application/octet-stream;

Or on apache2/httpd add this to your configuration or .htaccess file that is placed in .well-known/openpgpkey/hu:

<IfModule mod_mime.c>
  ForceType application/octet-stream

To verify that you did everything works as expected, you can try the WKD checker by wiktor.

Supported clients

All this would be useless without client support, but that’s the great news, a lot of clients already implemented it. Besides the GnuPG CLI itself, there is also Enigmail that does auto-discovery, Outlook with GpgOL, Kmail, and more.


When you are owning a domain and using it for email, you should make it as easy as possible to send you encrypted emails for secure communication. WKD provides an wonderful, practical and easy way to discover keys for mail addresses. Thunderbird with Enigmail simply switches to secure communication as soon as you finished entering the mail address, given there is a key for it.

When you have the chance, use OpenPGP for email. It keeps your communication private and setting up key discovery is a piece of cake. So what are you waiting for?

Feel free to reach out to me on Mastodon, by email (of course encrypted 😉) or any other way.

Update 2019-02-05: Thanks to wiktor for pointing out some technical mistakes.

Photo by CMDR Shane on Unsplash