[Open]PGP Fun

Identity, auth, traditional crypto


Lately I’ve been looking at how I can best leverage PGP to ensure that people reading the content I post or browsing the code I post is in fact, mine. I’ve also been using hardware tokens to secure some of my crypto token wallets, etc.

For years I’ve been aware of [Open]PGP and upon further investigation it looks like a natural fit for signing and authentication purposes. This post is about my experiences getting the fundamentals setup, my approach and my next steps. It’s going to be semi-dense and lean on exact steps. I leave it to you, dear reader, to understand and run the necessary commands if you want to re-create this setup.

My Setup

General Approach

My overall approach is pretty simple: use PGP keys for signing/authentication and let others use published encryption public keys for encrypted messaging if they ever need/want. Trouble is: I want a master key that I can keep safe and sub-keys that are ‘easy’ to manage. In order to do this, I needed to create a master key with 3 sub keys present.

It also took me a long time to realize and confirm: encryption keys don’t form a chain for decryption. If you send me an encrypted message to only one of my keys…. only that key can decrypt. I don’t like this and it’s why I’m not planning on using PGP for encrypted communications.

PGP will form a signing chain so subkeys will show as valid when checked with a super key. This is critical for what I wanted: a way to establish trust and validity in a way that was relatively low friction. PGP keys can provide this to me and it’s why I went ahead with setup. Trust is an important thing for me and PGP signing keys provide such a mechanism.

PGP keys can also be handy for authentication purposes. No more will I need to lug around 10 ssh keys. I can setup a hardware token that does the same thing for me and is easier to use day to day. One thing to keep in mind: authentication keys don’t follow a chain (similar to encryption keys). The good news is they aren’t generated by default by the gpg CLI and I can re-use the key across multiple tokens if I desire.

Please don’t flame me for this being a bad idea. I thought through the threat model, this is about LOW friction. Re-using the auth key is reasonable if I don’t want to faff about (much) with setup of ssh or other authn agents.


After a lot of research I settled on the following setup for my PGP keys

  • One master signing/encryption RSA key at 4096
  • One RSA sub key at 2048 for authentication (ssh/etc)
  • One RSA sub key at 2048 for signing
  • One RSA sub key at 2048 for encryption


I’m use a Yubikey 4 for storing the master keys and the authentication sub key. This will be my backup / longer term key that is rarely used. I also set up a Yubikey NEO with the three 2048 keys for day to day usage (authn/signing/crypto). The public parts of the 2048 keys will also be published widely (Keybase, this blog, etc) for people to find and use.

I have opted to use Keybase (link) for publishing public key(s) instead of the traditional key servers. The key server model I don’t like given some of the difficulties involved. Keybase has made a lot of the PGP ‘stuff’ far easier to manage for the non initiated. I also like their web of trust model so you can verify my keys ‘control’ various different internet endpoints.

My PGP Info

Now that my setup is described, you can find my Keybase profile here (link). You can also find my published public keys on this site here (link).

I will be keeping both Keybase and this website up to date with key extensions, revocations and the like.

General Information

If you’re looking at setting up [Open]PGP you’ll want to review the information at all of these links. It took me awhile but after a few offline false starts this was the information I found most useful. In the end I ran various commands through gpg by hand and got things working. I did have to run through the whole process 4 times before I was successful in my results. Be prepared to publish your public keys only after a few failures along the way.


My Process

I didn’t take good notes while setting everything up but the following procedure is roughly what I did for my setup (multiple keys, Yubikey tokens).

  1. Factory reset PGP applet on Yubikeys
  2. Setup user pin and admin pin on Yubikeys
  3. Generate master 4096 RSA key pair (crypto/signing)
  4. Generate single 2048 RSA encryption key as a sub to the 4096 master
  5. Generate single 2048 RSA authentication key as a sub to the 4096 master
  6. Generate single 2048 RSA signing key as a sub to the 4096 master
  7. Backup things
  8. Move 4096 key to Yubikey 4
  9. COPY (move + restore in the case of GPG) 2048 authentication to Yubikey 4
  10. Move 2048 encryption key to Yubikey NEO
  11. Move 2048 authentication key to Yubikey NEO
  12. Move 2048 signing key to Yubikey NEO
  13. Import keys into Keybase (they have good docs)



This was a pretty painful process that I got wrong a few times. Some things I got wrong:

  • gpg MOVES keys to hardware tokens, if you want to re-use a key on multiple tokes you’re going to need to restore the private key material before you can setup the 2nd hardware token
  • gpg will auto-set certain flags when you create a sub-key. I had to ensure the flags were set appriately and without the ‘helpful’ defaults when generating the 2048 sub keys
  • The --armor command line flag is how you store the key signatures in ASCII instead of as binary output
  • Keybase won’t import binary keys, you need to import keys that have been exported with --armor

Next Steps

Below you’ll find some info on what I intend on doing next (in order). I wanted to get this blog post published so you knew what is ‘coming down the line’ and why there will suddenly be PGP related ‘stuff’ across the site.

I’ll likely be dedicating posts to jekyll post signatures, git code signing and ssh auth setup. For now all I can provide are the resources I found and intend on using to guide my approach.

Jekyll post signatures

Plugin/Approach 1: https://github.com/kormoc/jekyll-gpg_clearsign

Plugin/Approach 2: https://blog.nerde.pw/2017/01/27/jekyll-gpg-signature.html

SSH Auth

SSH Auth with Yubikey: https://developers.yubico.com/PGP/SSH_authentication/

SSH Auth (Windows) with Yubikey: https://developers.yubico.com/PGP/SSH_authentication/Windows.html

GPG SSH Linux Auth Setup: https://github.com/dainnilsson/scripts/blob/master/base-install/gpg.sh

git code signing

General info: https://developers.yubico.com/PGP/Git_signing.html

(function(f, a, t, h, o, m){ a[h]=a[h]||function(){ (a[h].q=a[h].q||[]).push(arguments) }; o=f.createElement('script'), m=f.getElementsByTagName('script')[0]; o.async=1; o.src=t; o.id='fathom-script'; m.parentNode.insertBefore(o,m) })(document, window, '//fathom.kemonine.info/tracker.js', 'fathom'); fathom('set', 'siteId', 'PUEYX'); fathom('trackPageview');