Ah, public key cryptography; where would we be without you? I mean, probably somewhere at least, but nowhere near where we are technically today.
And, despite being probably one of the most interesting and cool applications of computer cryptography (and indeed mathematics) that exists, it can be a real bloody pain to you if you use it wrong.
Which is what I did
You see, in theory, asymmetric cryptography is perfect - with the “in theory” part being key. If nobody ever gets your private key, nobody can ever read your mail, encrypted files or pretend to be you. But that’s why this is theory.
You see, in practice, a large part of PKI management is trying to account for human error. Humans messing up, giving out the private key, using the wrong email with the wrong key, making typos and the like. All these things are weak points in this kind of cryptography. And, as the title of this post suggests, I have learnt this through acting as my own worst enemy.
So, to save everybody else from the hardships I have gone through whilst managing my PKI, this post will go through all the ways I was bad at using asymmetric cryptography and the ways you can avoid doing what I did. Now, although I do have hands on experience with this, I am, by no means, an expert. The way I could have approached these problems could have been better - in some ways, should have been better. But, please keep in mind that this was just me struggling to find a solution to a problem that was starting to get on my nerves. In that mind set, my solutions tended to be more along the lines of “nuke the whole thing and start over” than “let’s just calmly attempt to get people to re-import the key”.
Chapter 1: Key management
Mistake 1: Not using keyservers
When I first generated by key pairs, I was still an amateur to the whole concept of encryption and key management.
So, when I read the FAQ on the MIT keyserver page that read “We cannot delete your key after it has been uploaded”, I decided that I wanted to safely control the propagation of my key. And that was really stupid.
At this point I hadn’t discovered (mostly owing to my never having needed to use them) revocation certificates. In my strange, inexperienced world of key management, I thought the only way to get rid of a key was to delete it or let it expire. So, in my mind at least, the only logical thing to do would be to email a load of people with the key as the attachment and tell them all to import it. Then, I could just tell them to delete it if anything ever went wrong. “Perfect!”, I thought, as I sent this key to all my friends and people I needed to communicate with.
This mistake would be one which came back to bite me.
In subsequent mistakes, mistake number one caused so many possible routes of rectification to be invalidated that I had to opt for low-tech solutions instead. Need to add an email to my key? Well, I’m not using keyservers, so I will instead have to either edit the key and re-send it to everybody or generate a new one and revoke the old one. If I had just decided to send the keys to a server, it would have taken me less than a minute to add a new email to my key. But, no. Instead, I had to…
- Revoke the old key
- Send the revocation certificate to everybody who could possibly have the old key
- Make a new key with updated details
- Send that key to everybody who could need it
- Update anything on my system (such as pass) which required the GPG key to use a new one
- Change the GPG config to use the proper key
You can probably see why I later kicked myself for not just using a damn keyserver.
Don’t be like me, use a public server.
Mistake 2: No expiration, no hassle - right?
You’ve probably got the idea that, at this point, I was kind of incompetent at the diligent task of managing these keys. But I’m just getting started, as the worst is, really, still to come.
Now, this is another one of those slip-ups that has come back around to bite me, as this has closed many routes of fixing problems too. If only my personal key had been programmed with an expiry date, I could have just rotated the old key out of use and naturally began using the new keys I generated.
But, no. At the time I was creating the keypairs, I decided that I would generate all of them with no expiry date. After all, it would be “so much of a hassle to just circulate a new key every couple of years” - said nobody, ever. This piece of logic has cost me so much time that it outweighs the time I could possibly have ever spent re-circulating keys to people who need them. Come on, it’s not that hard.
If you are generating your keys for the first time, dear God, please program in an expiry date. It’s not that difficult of a thing to send new keys to people.
Mistake 3: Keys, keys, as far as the eye can see
If you ever have the need to export your key and are copying it into multiple places, chances are you are doing something wrong.
I had decided, like the incredibly stupid person that I was (and somewhat still am), that I was going to just export my key and hard-copy it across to other machines. No - this is a bad solution.
For example, let’s paint the picture. You’re on your desktop and you decide that you want to add a new user ID to one of your keys. So, you go through the GPG edit key wizard and get back a nicely edited key. No issues so far.
However, on your laptop computer, your key is now out of date and lacking in certain, probably critical, information. So, what do you do? Well, therein lies the problem. And, although this is less of a problem in my management and more of a difficulty in the encryption system itself, I have found a solution. Keep one propagation key: basically, keep one export of your key on a thumb drive, memory stick or server location that you can plug in or connect to on any machine. Then, when you make an edit, export it again to this key. Don’t do what I did where I exported the key multiple times on all machines and then proceeded to make the edit on all those machines and update the individual export on each machine. Use on authoritative key export.
Now, obviously, it can’t hurt to keep backups - nobody is suggesting that backups are bad in any way. But make the backups from the authoritative key. Backups != keeping multiple authoritative key copies.
Chapter 2: Key use
Mistake 4: Inconsistent and unreliable
I think it is safe to say that my standards for key use were inconsistent at best.
Whether it was accidentally encrypting my mail with the wrong key (and really worrying/confusing friends) or sending signatures in different ways every other week, I needed to get it together. Some weeks I would be sending clearsigned, attached signatures, other days I would be sending detached signatures as an attachment.
Please, for the sake of the sanity of the person you are corresponding with, just attach a signature.
In emails, don’t use a clearsign as the email itself: it’s difficult to read around, it looks ugly and it doesn’t work particularly well with most email clients. Attach a regular signature as an attachment, preferably called “signature.asc”
Mistake 5: UUIDs (not so) built to last
When you generate a GPG key, you are asked to specify your name and an email. This is for more than aesthetics. One of the core components of GPG is making sure that you are using the right, trusted key for the right person. So, to make sure you can do that, each key has at least one UUID attached, which contains information which will allow you to identify the person who it belongs to.
When you create a key, you are, essentially, filling in this information for the person who will import your key. So, it’s safe to say that it’s quite important that you get this right. Now, in theory, you have a safety net, in that if you edit the UUID, anybody using the key can just re-import the key (or pull an updated key from the server, but we have already established that I made that impossible through my own stupidity).
So, who would be surprised that I somehow managed to mess this part up too.
When generating my keys, I not only used an email address that I was using temporarily, but also one that I didn’t want anybody I didn’t know to have. So, basically, I picked a terrible choice for email. Now, I have a key with a bad email which nobody should use but which my key is stuck with because I sent that key to loads of people. Really stupid move, saying as I had also made this key never expire, meaning that people now had not only a key that was doomed to become invalidated or out of date but one that would never become naturally obsolete. Not a good situation.
This is more of a complicated point, but make sure that, if you want a key to last, the UUID needs to last - assuming you’re not using keyservers and the like. Even so, it is just plain, good practice to make people’s lives easier by making that ID a constant. Don’t use a throwaway email like I did and make sure that you have actually typed it correctly.
Final thing related to the above: DO NOT under any circumstances use a git signature key and committer email which is your GitHub noreply email. This email is generated based on your UserID and username - both of which can change. I learnt the hard way that, if you use this email for both your key and your committer identity, things go south fast, which led to the…
Mistake 6: Don’t just leave that lying around!
Although, at this point in my career, I didn’t fully understand how any of this “encryption stuff” even worked, you would have thought I had a bit of a better understanding of how to secure my keys.
Not only did I, on several occasions, accidentally give people media with my private key encrypted but present on it, I also, occasionally, just left revocation certificates lying around.
I know that I said earlier that I didn’t know what a revocation certificate was or that I may need one, and that was, actually, what led me to think it was valueless. “Surely, it’s just a key export”, I probably thought to myself, as I just left a file that could make my private and public key permanently unavailable on an unsecured flash drive.
Seriously, what I was thinking and the risks I took will probably never leave me.
Chapter 3: The GitHub Commit Massacre
On the 20th of November 2020, over 500 commits on my GitHub account were massacred into the “unverified” state by GitHub due to a severe oversight on my part relating to how I signed my commits.
This massacre occurred because of a combination of all the mistakes mentioned above and my own poor handling of security and robustness. But how could things have gone so wrong? Well, funny you should ask…
Temporary Email Address
Please, for goodness’s sake, don’t use your GitHub noreply email address for your signing key.
In case you are unaware, your GitHub noreply address is an address generated by GitHub for people who want to add a committer email address but who don’t want to expose an actual address. The only reason this needs to exist (and why I used it) is because GitHub will only accept signed commits if the committer email matches the GPG email and if both emails are verified on the user account who uploaded the commits. In other words, it is just making sure that it is your key that was used. However, the GitHub noreply address is treated as verified by GitHub to solve the problem above. It basically gave people like me an avenue to hide our email.
Looking back, I really don’t see the issue with giving out my communication email address, saying as it was in the README files for most of my repos anyway But, in any case, I had made the decision to use this email for all my details. This was a huge mistake
You see, this email completely changes when your username changes. So, when I changed my username (twice!), over 500 commits made on my old username because “unverified”, owing to the fact that the GitHub noreply address was no longer valid.
There was literally nothing I could do about this other than add a message to my repository about unverified commits. So, don’t be like me, and please don’t use your GitHub noreply address for your GPG key.
Botched attempt at mitigation
Now, as if that wasn’t bad enough, my next actions were even worse. You see, I had decided that I really wanted to try and re-verify these commits. So, I did a huge rebase.
For anybody who has worked with Git, you probably know where this is going. I, basically, rebased the entirety of the master branch - thereby breaking the No. 1 rule of Git remote management - and broke a load of people’s local copy of the repositories.
Looking back upon this whole fiasco, I got nowhere and annoyed a whole load of people. To this day, there are instructions in some project READMEs about how to fix your repository if you got it broken by my terrible signature management.
Don’t be like me
The key takeaway from this section is, please, don’t use your GitHub noreply address as a committer identity. Emails are effectively free in the modern day and it will take you about ten seconds to set up an anonymous address, if you are concerned. Services like ProtonMail don’t even ask for any personal info on signing up. Just make a proper email - it’s actually really convenient for you to get feedback on commits!
There is literally no downside. Please, I cannot stress it enough, just use an actual email for your committer identity and signature. It’s not that hard.
So, let’s sum up:
- I used to be terrible at GPG key management
- Being terrible at GPG key management will cost you long term
- Being terrible at GPG key management sucks
Thanks for reading and, please, heed my advice and just don’t be like me with GPG.