OpenPGP key statistics

Recently there has been some talk about the number of OpenPGP keys available on the various keyservers. My own contribution to this discussion is tracking the development at . As can be seen on both the line chart of total number of keys, and the breakdown to a bar chart for daily addition, new keys are added at a higher rate today than it was just a few years ago, and without any statistical considerations, the change of rate seems to coincidentally correspond to the Snowden leaks.


LineChart BarChart

This post will look into some of the underlying data and hopefully provide a bit more information depth. The data was exported from one of my own keyservers yesterday and consists of 3,526,080 primary keys, of which 118 keys were invalid to the point that I've discarded them from the rest of the analysis (unable to properly parse the OpenPGP packets to extract the information). To emphasize; I have not looked into subkeys in any way for the purposes of this post and I have made no attempt to determine whether these keys are expired, revoked or otherwise inactive.

The overall majority (94.74%) were Version 4 keys c.f. RFC4880 with V3 keys representing 4.73% and V2 keys representing 0.53%. DSA keys represented 74.4%, while 25.6% were RSA keys and a minority ElGamal (0.03%), Elliptic Curve keys (35 keys) and keys in the experimental range (32 keys) .

The key lengths spans from 3 keys in the experimental range key with algo id 103 of 224 bits to 32,768 bits (3 keys, two of which are RSA and one DSA). Due to the low occurrence of ECC keys (that have an expectation of lower key lenghts for similar expected security levels -  normally in the 256-521 bit range, although there is a strong possibility that the aforementioned 224 bits keys should also fit in this category) I have not done any adjustment for these. A full 77.4% of the keys are included when looking at the aggregate figures up to and including 1024 bits, roughly 2.7 million of the keys, and the corresponding number when looking at a 2048 and 4096 bits respectively are 95.3% and 99.95% of all keys included.


Load-balancing SKS

The synchronizing key server (SKS) is the most used implementation of OpenPGP key servers. Despite its many strengths, however, its web frontend scales badly and should generally be placed behind a reverse proxy such as nginx, apache or varnish. For inclusion in the High-Availability (HA) pool of this is a requirement, and it is also part of the weighting criteria for the various geographical sub pools. With the increase in number of keys I've been thinking of ways to ensure that the pool stays even more responsive, and currently considering (i) to make it a hard-requirement for inclusion in the pool to have a reverse proxy set up (ii) to reuse the HA pool for a set of servers that are even more available, by proving that they are load-balanced across multiple instances of SKS.


My own keyserver, for historical reasons named ( was located in another server facility and is currently not operational),  is running such a load balanced setup using Nginx's upstream module.But before getting back to that, some basic information about my SKS setup.

Two or three SKS servers (depending on whether I need to use one of them for experimenting with other projects such as the Key Signing Party list auto-generating lists based on publications to a keyserver) are running on different Virtual Machines, one server peering with the global network and the other servers peering internally. To ease the load on SKS, static pages are served by nginx directly using:

location / {
root /var/sks/web;
index   index.xhtml;


The actual data being served by SKS is in the /pks subdirectory and is being handled by the directive

location /pks {
proxy_pass http://sks_servers/pks;
proxy_pass_header  Server;
add_header Via "1.1";
proxy_ignore_client_abort on;

And this is where the load-balancing is starting to happen. "sks_servers" is not a hostname that is being referenced but an upstream directive in Nginx that states;

upstream sks_servers
server  localhost:11372;

When adding and removing servers I simply edit this directive and reload nginx, and here I also have the possibility of assigning weights to each of the servers (defaults to 1).
In the status list of the pool such load-balanced servers can be identified by a blue flag for RProx (Reverse Proxy). Hopefully enough operators will set up load-balanced systems for an even more responsive High-Availability pool to exist.


New OpenPGP key generated utilizing Elliptic Curves

I have generated a new OpenPGP key that I will start migrate over to immediately, however, I do not really expect to revoke my current keys within the next few years for reasons found below. But before getting into that - the new key info. As per my usual setup the encryption subkey has a one year expiry. (I've also updated the keys 0x16E0CF8D6B0B9508 and 0x0B7F8B60E3EDFAE3 with new encryption subkeys for next year)

pub 521E/43FE956C542CA00B created: 2012-10-07 expires: never usage: SC
sub 521e/063FC02F1BFDEAA8 created: 2012-10-07 expires: 2013-12-30 usage: E

Why do I expect such a long migration path?

This key is an Elliptic Curve Public key following RFC6637. It is using a NIST curve of an ECC strength that is 521 bits, which relative to an RSA key should be about 15,360 bits. My RSA key that is this length apparently isn't supported in newer versions of GnuPG (version 2.1, that is using GPG Agent for storing the secret keys)

Currently the only implementation I'm familiar with that accept ECC keys is GnuPG 2.1, which is still in Beta. The SKS keyservers handle this type of key since version 1.1.4 and the sub-pool hkp:// require servers to be at this version, and is as such ECC safe .

The new key might also turn out to be replaced if we get an OpenPGP standard of versions 5 within a reasonable timeframe. Until then, contact me using whichever key you want - as long as you consider the value of your own privacy and is using one of them.