There are better alternatives than a key server
An OpenPGP Key Server might not be the best option for your use case, as it was designed for large databases with a possibility to add signatures that were used to maintain the web of trust. However, there were spamming attacks in 2019 and GDPR issues in 2021 that led to the shutdown of SKS based key servers.
While some services have come back with different software implementations and new controls against those problems, it was never intended for the use case described in this question. Furthermore, the current solutions are moving from the web of trust based infrastructure towards protocols utilizing existing centralized PKI like TLS or DNSSEC for backing up the authenticity of the public keys. Those are designed for this use case.
Automatically locating keys with GnuPG
Instead of gpg --keyserver or configuration keyserver, the command gnupg --auto-key-locate <mechanisms> or configuration parameter auto-key-locate is used for locating the key from several possible protocols used for publishing the key.
For example, if you would like to look for the key from WKD and DANE covered in this answer before querying the local keyring and the keyserver, you would put this in the gpg.conf:
auto-key-locate wkd,dane,local,keyserver
mechanism |
Description |
cert |
Locate a key using DNS CERT, as specified in RFC 4398. |
pka |
Locate a key using DNS PKA. |
dane |
Locate a key using DANE, as specified in RFC 7929. |
wkd |
Locate a key using the Web Key Directory protocol. |
ldap |
Using DNS Service Discovery, check the domain in question for any LDAP keyservers to use. If this fails, attempt to locate the key using the PGP Universal method of checking ldap://keys.(thedomain). |
ntds |
Locate the key using the Active Directory (Windows only). |
keyserver |
Locate a key using a keyserver. |
keyserver-URL |
In addition, a keyserver URL as used in the dirmngr configuration may be used here to query that particular keyserver. |
local |
Locate the key using the local keyrings. This mechanism allows the user to select the order a local key lookup is done. Thus using --auto-key-locate local is identical to --no-auto-key-locate. |
nodefault |
This flag disables the standard local key lookup, done before any of the mechanisms defined by the --auto-key-locate are tried. The position of this mechanism in the list does not matter. It is not required if local is also used. |
clear |
Clear all defined mechanisms. This is useful to override mechanisms given in a config file. Note that a nodefaultin mechanisms will also be cleared unless it is given after the clear. |
Server side
OpenPGP Web Key Directory (WKD)
There is an informational Internet-Draft that specifies the OpenPGP Web Key Directory; draft-koch-openpgp-webkey-service-19. The protocol allows discovering and fetching PGP keys from a HTTPS based directory that is maintained by the mail service provider (on the domain level) and does not publish a list of email addresses available, but uses hashes for the local-part of the email.
Setting up a static web server for this protocol takes some effort. There is also the possibility to install a Web Key Service that automates the creation of the static files, but it is not very user friendly either — as most tools related to PGP.
Once you have set up the Web Key Directory, you could test it with a command that disables all other mechanisms:
gpg --auto-key-locate clear,nodefault,wkd --locate-key user@example.com
DANE Bindings for OpenPGP
Rather then TLS PKI, DANE Bindings for OpenPGP relies on DNSSEC as its PKI. This option is faster to setup, and a good alternative if:
- There is a limited number of PGP keys to maintain, and they are not updated frequently.
- Your domain name already has DNSSEC enabled, or you can enable it.
- You believe that your contacts can or can be guided to enable DNSSEC on their DNS clients.
The abstract of RFC 7929 summarizes this protocol quite exhaustively:
OpenPGP is a message format for email (and file) encryption that
lacks a standardized lookup mechanism to securely obtain OpenPGP
public keys. DNS-Based Authentication of Named Entities (DANE) is a
method for publishing public keys in DNS. This document specifies a
DANE method for publishing and locating OpenPGP public keys in DNS
for a specific email address using a new OPENPGPKEY DNS resource
record. Security is provided via Secure DNS, however the OPENPGPKEY
record is not a replacement for verification of authenticity via the
"web of trust" or manual verification. The OPENPGPKEY record can be
used to encrypt an email that would otherwise have to be sent
unencrypted.
In short, you place an OPENPGPKEY DNS record for each key, that is located at a specific location, the local-part hashed.
<hash>._openpgpkey.example.com. IN OPENPGPKEY <public key in base64>
For example, if you have the following ed25519 key for user@example.com:
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ4uy0BYJKwYBBAHaRw8BAQdALuHNfdLF3cWO1z9SJOz6vcCYDxyA10e99vlZ
TfaU1x20F1VzZXIgPHVzZXJAZXhhbXBsZS5jb20+iJAEExYIADgWIQSFGjy/rC3T
K3ue3N9F+BxB0/vOHgUCZ4uy0AIbAQULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAK
CRBF+BxB0/vOHjyWAQCCPDuG3eGr0FRnE5hThdmpwJVTMiD16YlbPgXNF0xo4AD+
NVh6zT6kAQ+ztToNWvurGLh9BaI81ZQ1Mek0kqv9awA=
=GMNX
-----END PGP PUBLIC KEY BLOCK-----
The truncated (28 octets) SHA2-256 hash for local-part user:
$ echo -n "user" | sha256sum | cut -c1-56
04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c8
The OPENPGPKEY record would contain the entire public key:
04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c8._openpgpkey.example.com. IN OPENPGPKEY (
mDMEZ4uy0BYJKwYBBAHaRw8BAQdALuHNfdLF3cWO1z9SJOz6vcCYDxyA10e9
9vlZTfaU1x20F1VzZXIgPHVzZXJAZXhhbXBsZS5jb20+iJAEExYIADgWIQSF
Gjy/rC3TK3ue3N9F+BxB0/vOHgUCZ4uy0AIbAQULCQgHAgYVCgkICwIEFgID
AQIeAQIXgAAKCRBF+BxB0/vOHjyWAQCCPDuG3eGr0FRnE5hThdmpwJVTMiD1
6YlbPgXNF0xo4AD+NVh6zT6kAQ+ztToNWvurGLh9BaI81ZQ1Mek0kqv9awA=
)
There is also an online tool for generating the records:
Once you have set up the DNS record and DNSSEC, you could test it with a command that disables all other mechanisms:
gpg --auto-key-locate clear,nodefault,dane --locate-key user@example.com