Mon, 26 Dec 2011

Summary: It is important that we (the Debian community that relies on OpenPGP through
GNU Privacy Guard) stop using short key IDs. There is no vulnerability in OpenPGP and GPG.
However, using short key IDs (like 0x70096AD1) is
fundementally insecure; it is easy to generate collisions for short key IDs.
We should always use 64-bit (or longer) key IDs, like: 0x37E1C17570096AD1
or 0xEC4B033C70096AD1.

TL;DR: This now gives two results: gpg --recv-key 70096AD1

Some background, and my two keys

Years ago, I read
dkg's instructions
on migrating the Debian OpenPGP infrastructure. It told me that the time and
effort I had spent getting my key into the strong set wasn't as useful as I
thought it had been.

I felt deflated. I had put in quite a bit of effort over the years to strongly-connect my
key to a variety of signatures, and I had helped people get their own keys into
the strong set this way. If I migrated off my old key and revoked it, I'd be abandoning some
people for whom I was their only link into the strong set. And what fun it was
to first become part of the strong set! And all the eyebrows I raised when I told
people I was going meet up with people I met on a website called
Biglumber... I even made it my
Facebook.com user ID. So if I had to generate a
new key, I decided I had better really love the short key ID.

But at that point,
I already felt pretty attached to the number 0x70096AD1. And I couldn't come up with
anything better. So that settled it: no key upgrade
until I had a new key whose ID is the same as my old key.

That dream has become a reality. Search for my old key ID, and you get two keys!

I also saw it as an opportunity: I know that cryptography tools are tragically easy
to mis-use. The use of 32-bit key IDs is fundamentally incorrect -- too little entropy.
Maybe shocking people by creating two "identical" keys will help speed the transition
away from this mis-use.

A neat stunt abusing --refresh-keys

Thanks to a GNU Privacy Guard bug, it is super easy to get my
new key. Let's say that, like many people, you only have my old key
on your workstation:

You can see that it set out to refresh just 1 key. It did that by querying
the keyserver for the short ID. The keyserver provided two hits for that
query. In the end, GPG refreshes one key and actually imports a new key
into the keyring!

There is a
bug filed in GNU Privacy Guard about this.
It has a patch attached. There is, at the moment, no plan for a new release.

A faster attack, but nothing truly new

My friend Venkatesh tells me there is an apocryphal old Perl script that
could be used to generate key ID collisions.
Here in the twenty-first century, l33t h4x0rz like Georgi Guninski are
trying to create collisions.

In May 2010, "halfdog" posted a note to the full-disclosure list that generates PGP keys
with chosen short key IDs. I haven't benchmarked or tested that tool, but I have used a
different tool (private for now) that can generate collisions in a similar fashion.
It takes about 3 hours to loop through all key IDs on a dinky little netbook.

You don't have to use any of these tools. You can just rent time on an elastic
computing service or a botnet, or your own personal computer, and generate keys
until you have a match.

I think that it's easy to under-estimate the seriousness of this problem: tools
like the PGP Key Pathfinder should be updated to only
accept 64-bit (or longer) key IDs if we want to trust their output.

My offer: I will make you a key

I've been spending some time wondering: What sort of exciting demonstration
can I create to highlight that this is a real problem? Some ideas I've had:

Publish a private/public key pair whose key ID is the same as Phil Zimmerman's, original author of PGP

Publish a private/public key pair whose key ID is the same as Werner Koch's, maintainer of GNU Privacy Guard

Publish a set of public keys that mimic the entire PGP strong set, except where I control the private key of all these keys

For now, here is my offer: If you send me a request signed with a key in the strong
set, I will create a 4096-bit RSA public/private key pair whose 32-bit key ID is one greater
than yours. So if you are 0x517DD4E4 I will generate 0x517DD4E5.

I will post the keys here, along a note about who requested it, and instructions on how
to import them into your keyring. (Note: I will politely decline to create a new key whose 32-bit key ID would create a collision;
apologies if your key ID is just one away from someone else's.)

P.S. The prize for best sarcastic retort goes to Ian Jackson. He said, "I should go and create a lot of keys with your key ID. I'll set the real name to 'Not Asheesh Laroia' so everyone is totally clear about what is going on."