Publishing PGP keys on The Web

When the Web started becoming popular, one of the reoccuring newbie questions on the newsgroup alt.security.pgp became:

How do I put my PGP key in a web page without the lines wrapping?

The reoccuring answer, of course, has been:

Place the key between <PRE> and </PRE>.

Unfortunately, that's a bad answer. A better (but grumpier) answer is:

Don't even bother putting the key in an HTML file. It's an unnecessary mixing of file types and increases overhead. Put the unadorned keyfile on the server.

You probably want me to explain that answer. I can do that.

The way I see it, 99% of the people publishing their PGP keys on the Web have a hyperlink on their home page saying "Get my PGP key.", which leads to another HTML file that has a PGP key stuck in the middle of it. Readers who want to acquire that public key have to save the file (usually containing blatantly obvious and irritating observations like "This is my PGP key") and process it outside their browser.

This is bad web design, and a waste of bandwidth. Binary files (Yes, PGP keys are binary files, but don't tell your sysadmin, because he might rmgroup alt.security.keydist) should always be in separate files -- graphics, for example are referenced using "IMG", not base64-encoded and jammed in the middle of the page.

Remember, files accessed via http aren't required to be .html files! (You have noticed all those .gif files out there, haven't you?) Just put the .asc file on your web server and reference it with an URL like http://www.example.com/public.asc (I use public.aexpk instead of public.asc for my key -- more on that below.) If users follow that hyperlink, they'll get a file containing the PGP key, with no line wrapping, no HTML, and no perfunctory gibberish.

Congratulations. You've just saved a little diskspace and bandwidth, and given yourself some room for more technical improvments. Read on.

An Advanced Approach

If you're reading this site, you're probably ready to do even better. Here are three things you can do:

Use a better file extension

Some Windows and Macintosh versions of PGP associate the .aexpk file extension with PGP keys. If you use that extension for your public key, you make life a little easier for people who download your key (because you're making sure the key gets assigned a distinct icon when it appears on their screens), and you make it easier to configure your web server (because most webservers assign media types based on file extension -- see below).

Use the proper media type

Although you may think your web browser uses file extensions to tell the difference between HTML files and everything else, it doesn't. It uses the "Content-Type" header sent by the web server. If your browser sees a type it can't process itself, it will either give the file to another program, or ask you if you want to save the file.

Content-Type headers use the Internet Media Type values originally created for the MIME standard. RFC 3156 defines the media type for ASCII-armored PGP keys as "application/pgp-keys". Use that media type for your .aexpk or .asc files, and you'll make it easier for users to send your key directly to their PGP keyring.

(If you don't declare a media type for PGP keys, your webserver will probably default to "text/plain" (which opens the key in users' browsers), or "application/octet-stream" (the generic binary type that makes most browsers ask users if they want to save a file.)

Changing the media type assigned to given file extension is usually a one-line command in your server configuration file. For instance, an Apache user just has to put this line in an .htaccess file:

AddType application/pgp-keys .aexpk

(This is why using .aexpk for keys makes assigned media types easier, since most webservers limit you to one media type per file extension. Using .aexpk for keys saves .asc for when you want to publish signed or encrypted files.)

Use better HTML

Even if you're using the "application/pgp-keys" media type, you can link to your key like any other web page. It would be good manners, however, to include a type attribute in the link's markup. For example:

<a href="public.aexpk" type="application/pgp-keys">public.aexpk</a>

The type attribute doesn't really change how browsers handle the link, but it lets users who care about these things check the link's content type before they click on it. (For example, Mozilla will display the media type in a "Properties" box.)

Demonstration

Here's a link to my public key that uses all of the steps described above. If you want, click on it and see what happens.

If your web browser doesn't know what to do with the media type, take the opportunity to assign it to PGP. (If you're using a version of PGP that has a separate key-managing utility like PGPKEYS.EXE, use that instead of the PGP executable.)

Historical Notes

The original 1996 version of this article recommended using "Content-Type: application/pgp". That was before RFC 2015 officially defined the "application/pgp-keys" media type.

Some versions of this page also recommended distributing keys in binary format. That recommendation was rescinded when RFC 3156 updated the PGP/MIME standard to explicitly limit "application/pgp-keys" to ASCII-armored files. Binary public keys must instead be assigned the "application/octet-stream" media type, and may use the .bexpk file extension to differentiate them from ASCII-armored keys.

It only took eight years, but other people figured out how to distribute PGP keys in a proper format! (I'm not too thrilled about how he uses the link element, though.)

A Final Disclaimer

I should probably confess: I did have "a PGP key stuck in the middle" of my Slashdot user profile and my WhoWhere.com directory listing, because that's the only option they provided for distributing encryption keys. So if you're faced with a similar choice, don't feel too bad about it. I understand.