May 29, 2021

1096 words 6 mins read

Let's GPG like a paranoiac

This post assumes you have …

  • Installed rng-tools in your system.
  • Turned off your WiFi.
  • Pulled out the Ethernet cable.
  • Cellphones turned off.
  • Windows and curtains closed.

additionally the following considerations apply:

  • You’re totally off-line preferably in the woods, either alone or with a person you fully trust.
  • If not possible then a Faraday cage has been set up.

Let’s begin.

Generate the Master key

The story begins with a fly ticket to Vancouver, a live Tails USB and a copy of the GnuPG manual. The plan is to spend a weekend near a rain forest and take advantage of this year vacations to generate a new GPG key. After entering the tent plug the USB, select from the Boot menu the USB stick and boot from there, after getting a shell we begin the incantations:

$ gpg --full-gen-key --expert

We’ll generate a master key with different sub-keys for signing, encryption and authentication. Let’s go for an ECC as the master key and toggle the sign capability so that we use it only to certify.

  • ECC (set your own capabilities)
  • (S) Toggle the sign capability

So the allowed actions should say something like:

Current allowed actions: Certify

press q and let’s continue choosing the curve we want and the expiration of the key:

  • (1) Curve 25519
  • Key is valid for? (0) 5y

We don’t want to make our master key to never expire, although we should take utmost care with this key it is also possible some day could be compromised, keeping a relative short expiration period is a way to protect ourselves in case the revocation certificate was also compromised, of course if the passphrase is also compromised then it will not matter at all, Mallory wins.

Once we proceed, we’re asked to provide a UID to identify the key, type your Real name (I highly recommend it to be your real name) and your primary Email address, and please, DO NOT use a comment in the key, leave it empty.

Real name: John Doe
Email address: [email protected]
Comment:
You selected this USER-ID:
    "John Doe <[email protected]>"

We’re asked for a passphrase that should belong to your mind for your whole life and never let it slip through your mouth.

Generate single purpose sub keys

We now have a master key, it will show us the identifier of the key and can also see it with:

$ gpg --list-secret-keys --keyid-format LONG

It shows something like ed25519/AAD2813C433BEF7C, whatever is after the / is the identifier of the key. Let’s proceed to create the sub-keys:

$ gpg --edit-key AAD2813C433BEF7C --expert

And begin:

gpg> addkey

The signing key

The first we’ll create is a signing key, we know how to do this:

  • ECC (set your own capabilities)

Allowed actions must be as follows:

Current allowed actions: Sign

If not, toggle the sign and authenticate capability till you got it right. Select the curve and expiration, I want this to be shorter expiration time than the master key.

  • (1) Curve 25519
  • Key is valid for? (0) 3y

The encryption key

After this is done, we proceed to create an encryption key:

gpg> addkey

we’ll choose a RSA key for this:

  • (8) RSA (set your own capabilities)

and again, toggle the capabilities until you end at:

Current allowed actions: Encrypt

this time we’re asked to pick the key size, go with the maximum, at this moment this is 4096 bits 1, and set the expiration:

  • What keysize do you want? (3072) 4096
  • Key is valid for? (0) 3y

The authentication key

Finally let’s generate an authentication key:

gpg> addkey

and choose an ECC again:

  • ECC (set your own capabilities)

again, toggle around the capabilities until you have the allowed actions like so:

Current allowed actions: Authenticate

Select the curve and expiration date:

  • (1) Curve 25519
  • Key is valid for? (0) 3y

and finally

gpg> save

The revocation certificate

Now, in new versions of GnuPG you’ll have a revocation certificate automatically created for your master key, these are typically stored in ~/.gnupg/openpgp-revocs.d/ folder with the name being the keygrip of the master key, you can get the keygrip of your key like this:

$ gpg --with-keygrip --list-key AAD2813C433BEF7C
...
    Keygrip = 9BE90F631ACABADA63A33173AF3DEEA938222F874
...

This means you should expect a file like this to exist:

$ ls -1 ~/.gnupg/openpgp-revocs.d/9BE90F631ACABADA63A33173AF3DEEA938222F874.rev
/home/uid/.gnupg/openpgp-revocs.d/9BE90F631ACABADA63A33173AF3DEEA938222F874.rev

in case you do not see one then generate a revocation certificate like so:

$ gpg --gen-revoke AAD2813C433BEF7C --output GPG-AAD2813C433BEF7C.asc

do not give it any reason and save it with the same care your master secret key should be treated since this certificate turns your key unusable and it will come handy in case you have the key compromised.

The secret master key

Now let’s save an encrypted copy of the secret key so we can restore it later:

$ gpg --export-secret-key AAD2813C433BEF7C -a | gpg --cipher-algo AES256 --output sec-key.gpg -a --symmetric

This will ask you for the master key passphrase and a passphrase you want to set to the encrypted artifact, in case you want to deploy this backup at a later time you’ll need this to decipher it.

Now, you only need these two things, the encrypted master secret key and it’s revocation certificate, however many choose to backup the ~/.gnupg folder and that’s fine too, just keep it in a really secure, encrypted device.

Now, it’s time to destroy our key 2 (once the backup is in a secure place), once again find the keygrip and delete the corresponding file:

$ gpg --with-keygrip --list-key AAD2813C433BEF7C
$ rm ~/.gnupg/private-keys-v1.d/9BE90F631ACABADA63A33173AF3DEEA938222F874.key

take note, it might be the case the *.key filename is the key identifier instead of the keygrip.

Now our key is gone, we only have our backup in a secure encrypted device, our key will never see the light again (we hope) and no one in this forest knows what just happened.

A new passphrase

Let’s now set a simpler passphrase on the key or at least a different passphrase that we could use on a day to day basis without fear.

$ gpg --edit-key AAD2813C433BEF7C passwd

We’re now done.

The public key

Now we need our public key so that someone can verify our identity, for this let’s export it:

$ gpg --armort --export AAD2813C433BEF7C

The output you can share it with anyone, use it on GitHub or whatever you like.

Have fun!


  1. You can build GPG from source and increase this to 8192 bits or more but there’s little benefit in doing so. ↩︎

  2. To securely remove a file use something like nwipe or dd random bytes into the device. Or destroy the HDD after you finished, that works too. ↩︎