Making GPG Fingerprints Friendlier
I received a keybase.io 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:
#!/usr/bin/python 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], print
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.