Not Safe From Wolves

Making GPG Fingerprints Friendlier

I received a invite from @whiskers75, and have set my profile up.

It’s really an ingenious idea: taking away the difficulty of establishing that the owner of a given key is who you think it is- if they can prove control of a Twitter or GitHub account, or web hosting for a domain that you recognise, then you can verify these proofs against their key.

For most the interactions I have online (especially anything that would be signed or encrypted) people are more likely to know me as @insom than to have met me in person.

They show the last 64 bits of your key fingerprint on your profile, which is important, but I can’t help but feel that fingerprints are still super unfriendly. I used to have mine on my business card at Crestnorth – this did not make proofing my business cards any easier, or win me any friends at the printing company.

PGPfone used to have users read out a series of words to validate that the connection was secure and that they were talking to the person whom they expected to, with no one listening in.

I was always surprised that this didn’t catch on more widely. The /usr/share/dict/words on my Macbook has 235,886 words – enough for 17 bits – but it contains words like “phyllophyllin” – not great for use over the phone.

A better fit for my purposes, is Ogden’s Basic English Word List – a list of 850 words which are considered “basic English” – and useful for learners. This excludes most technical and specific words and ensures widely pronounceable words are chosen. I copied and pasted my word list from here.

[ After writing this post, I’ve become aware of a standard word list used for this – the PGP word list – oh, well, it was just a quick hack, anyway. ]

The largest power of two under 850 is 2^9, so we’re going to break the fingerprint into 9 bit chunks and then use that 9 bit integer as an index into the alphabetised word list:

import sys
words = [x.strip() for x in open('words').readlines()]
fp = sys.argv[1]
fp_as_long = long(fp, 16)
nine_bits = (2 ** 9) - 1
# 64 / 9 is 7.1 - round up to 8 to use all of our bits.
for i in range(8):
    word_index = fp_as_long & nine_bits
    fp_as_long = fp_as_long >> 9
    print words[word_index],

And we’re done! Giving it my fingerprint of 8CCE 2412 3B8F 78F8 I can generate the phone-call-friendly fingerprint of:

fact minute effect bitter berry card base able

Mmm. Bitter berries.

Last updated:

This is archived content. New updates will appear on