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!