logo
Jiff Slater
🤔 About
✍️ Contact
📚Knowledge
30 Jul 2021
These articles have been archived. You may find them useful but I am no longer offering support for them. Check out my latest articles on plkt.io.
Using GPG to master your identity (Part 1)
29 March 2019

I’ve steered clear of GPG for a while simply because I never implemented a reliable method of storing my keys. Now, with cloud storage, authenticated symmetric encryption, and hardware keys, I believe I can no longer worry about losing my keys. Forgetting the passphrase is a different matter, mind you.

I’ll be showing you how to create a reliable set of personal GnuPG keys you can use for authentication, authorisation, signatures, and encryption. These keys should stay with you for years to act as your sole source of truth. You do trust yourself, don’t you? 🙂

These examples will exist completely separately from your actual key so to speed up the tutorial I will use simple passwords. In your actual keys, well… you know the drill: use long passphrases that you generate from somewhere and then mutate the results. I usually suggest GRC Perfect Password Generator and some dice.

First, make sure you have GnuPG installed. This software provides a full implementation of the OpenPGP standard. I’m using version 2.1.18.

# apt install gnupg

And, we’ll use our own custom invocation of gpg just for this tutorial.

$ mkdir $HOME/gpgtutorial
$ cd !$
$ alias gpgh="gpg --homedir=$HOME/gpgtutorial"

Let’s jump right into it. We’ll generate a key right now without a passphrase. This will use the batch functionality so we don’t have to answer any prompts. The terminal will appear to hang but that’s because entropy is being generated so wait a while for it to complete. This process took 2 minutes on my machine.

$ gpgh --batch --pinentry-mode loopback --passphrase '' --quick-generate-key "Antony Jepson (test account) <mail@domain.tld>"
gpg: keybox '/home/local/gpgtutorial/pubring.kbx' created
[wait 2 minutes]
gpg: /home/local/gpgtutorial/trustdb.gpg: trustdb created
gpg: key 5F3720AC7BE7F124 marked as ultimately trusted
gpg: directory '/home/local/gpgtutorial/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/local/gpgtutorial/openpgp-revocs.d/B68449CF613EC70C13CC2ABE5F3720AC7BE7F124.rev'

Let’s look at the details of this new key and directory structure.

$ ls
openpgp-revocs.d private-keys-v1.d pubring.kbx pubring.kbx~ trustdb.gpg

The openpgp-revocs.d directory contains your revocation certificates. You can use these to say you no longer want a certificate to be valid. The private-keys-v1.d directory contains your private keys. The pubring.kbx keybox file contains all your public keys with the ~ suffix representing the GPG agent’s backup. The trustdb.gpg file contains your personal web of trust.

$ gpgh --list-signatures
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2021-03-27
/home/local/gpgtutorial/pubring.kbx
-----------------------------------
pub rsa3072 2019-03-28 [SC] [expires: 2021-03-27]
B68449CF613EC70C13CC2ABE5F3720AC7BE7F124
uid [ultimate] Antony Jepson (test account) <mail@domain.tld>
sig 3 5F3720AC7BE7F124 2019-03-28 Antony Jepson (test account) <mail@domain.tld>
sub rsa3072 2019-03-28 [E]
sig 5F3720AC7BE7F124 2019-03-28 Antony Jepson (test account) <mail@domain.tld>

You can see that this key was generated today and expires 1 year and 355 days from now. It consists of a public key that can be used for Signing and generating a Certificate. We have two signatures and the encryption signature has a trust level of 3. Finally, there’s a sub key that we can use for encryption.

I consider this initial set of keys the master keys. These are the keys you should do your utmost to keep safe. For day-to-day use, we will generate a set of sub keys for each required identity. For example, let’s generate a sub key to use with Github in order to sign our commits.

$ gpgh --edit-key "Antony Jepson"
Secret key is available.

sec rsa3072/5F3720AC7BE7F124
created: 2019-03-28 expires: 2021-03-27 usage: SC
trust: ultimate validity: ultimate
ssb rsa3072/0EDE2324F25F7767
created: 2019-03-28 expires: never usage: E
[ultimate] (1). Antony Jepson (test account) <mail@domain.tld>
gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072)
Requested keysize is 3072 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 2y
Key expires at Sun 28 Mar 2021 09:50:21 BST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

[Prompt for passphrase - I left this empty]

sec rsa3072/5F3720AC7BE7F124
created: 2019-03-28 expires: 2021-03-27 usage: SC
trust: ultimate validity: ultimate
ssb rsa3072/0EDE2324F25F7767
created: 2019-03-28 expires: never usage: E
ssb rsa3072/E3114D5381DE17CF
created: 2019-03-29 expires: 2021-03-28 usage: S
[ultimate] (1). Antony Jepson (test account) <mail@domain.tld>
gpg> quit
Save changes? (y/N) y
$ gpgh --list-keys --keyid-format long
/home/local/gpgtutorial/pubring.kbx
-----------------------------------
pub rsa3072/5F3720AC7BE7F124 2019-03-28 [SC] [expires: 2021-03-27]
B68449CF613EC70C13CC2ABE5F3720AC7BE7F124
uid [ultimate] Antony Jepson (test account) <mail@domain.tld>
sub rsa3072/0EDE2324F25F7767 2019-03-28 [E]
sub rsa3072/E3114D5381DE17CF 2019-03-29 [S] [expires: 2021-03-28]

Now we have a new subkey that can only be used for signing. Git already has a premise for using this key when creating commits.

$ git config --global user.signingkey E3114D5381DE17CF
$ gpgh --armor --export E3114D5381DE17CF

Now you can paste the exported key into the relevant Github section in settings to sign your commits both on and off the website.

There’s a lot more to discover with GnuPG. I’ll be covering the process of keeping these keys secure in another post.