Getting Started With GPG - Generating Keys

Exploration into the GPG platform and how to use it

In an increasingly online world, we’ve become accustomed to being able to download anything from anywhere. Usually, we never think twice about where that download is coming from or who is on the other side, or even worse, who might be listening in or changing things in flight. Sometimes that doesn’t really matter. Like this site. There’s no dynamic content in this site and it’s built using HUGO. Nothing can really change (unless your government or ISP is censoring this site). But sometimes it really matters. You need to make sure you’re going to your bank’s website. You need to make sure that you’re putting your password in the real amazon.com. With the web, we use SSL for this. It’s the padlock in the upper right hand corner of your browser that says “Connection Secured” whenever you go anywhere these days. But how do we secure files and make sure they were put there by someone we trust?

GPG (The GNU Privacy Guard) is a software that lets us do this. It’s based on a “web of trust” that helps to ensure that no broken, compromised, or otherwise expired keys should ever break the trust of any other keys. That’s a fancy way of saying that it is decentralized. There’s a lot of buzz about that right now! With GPG, people generate their own Master Certifying Key, from which they can create various sub keys to encrypt, authenticate, or sign files and messages. The certifying key is used to sign other keys as well, which says that they are trusted. So, if I have a friend, Bob, and we sign each other’s keys, we are saying to the whole web of trust that anything that Bob trusts, I trust, and anything that I trust, Bob trusts. This is transitive. So if Bob also trusts Sam the same way that I trust Bob, then I will as well. However, there’s some additional protections, where this relationship is weaker, and will require multiple indirect relationships to be trusted, so no one link in the chain will affect all others.

That was a lot of talk about keys, but not a lot about encryption, which is the meat and potatoes of GPG. Keys give us the ability to encrypt, sign, and authenticate. So let’s get started.


# Generating a Master Certifying Key

  1. First, we have to generate our new keys. This is best done on an air-gapped computer that will never touch the internet again. However, this is not necessary to use GPG, it just keeps your master key much more Secure by removing the opportunity for a data leak. Use the command gpg --expert --full-generate-key to generate a new key. You’ll get a prompt asking you to select a key type. Select option 8 to generate an RSA key. (there are other options, but they’re not as widely in use right now).
gpg (GnuPG) 2.4.5; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC (sign and encrypt) *default*
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key
  (14) Existing key from card
Your selection?
  1. Next, the program is going to ask us what capabilities we want for our key. We want to toggle everything off except for Certify, and type q when finished.
Possible actions for this RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished
  1. Next, we have to set our key length. It’s wise to make our key as long as possible so we can be prepared for the future, but it can make encryption slower. It depends on the key type. In my case, the longest is 4096, so I’ll select that.
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
  1. Next, we need to select when the key is set to expire. I chose “never” because I keep my key secret and air-gapped. If you don’t keep your key air-gapped, I’d advise you set some expiry date a few years in the future so in case it gets compromised, the damage that could be done is minimal. It will ask to confirm, and you’ll have to confirm your choices.
Requested keysize is 4096 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)

Key does not expire at all
Is this correct? (y/N)
  1. Next, we’ll have to give it our real information. Anonymity is not really an option here unless you have a pseudonym. I don’t, so I’m using my real name and a test email from my domain. Again, you’ll be asked to confirm.

GnuPG needs to construct a user ID to identify your key.

Real name: Matthew Krueger
Email address: example@matthewkrueger.com
Comment: Matthew's Example Master Certifying Key for Website
You selected this USER-ID:
    "Matthew Krueger (Matthew's Example Master Certifying Key for Website) <example@matthewkrueger.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?
  1. We’ll now be asked to enter a password for our master key. This is VITALLY important if you’re not keeping your key air-gapped, as this will encrypt your key when not in use. Since this is a demo, I’m not going to enter anything here. Every OS and implementation of GPG will be different, so follow the prompts it gives you. Once again, I’d like to emphasize the VITAL importance of choosing a unique, complex, and random password for your key. I keep mine written down on a physical piece of paper that never touched a copy machine (they spy on you), and I sent copies to my family across the state. While that’s a bit extreme, similar concepts are still good to follow, especially offsite backups. You don’t want to lose your key. Ever.

  2. Lastly, GPG will generate our key and give us some information. The line pub contains a number, 64CFA56B02F7B2E484B09BE29F9F051089326E60. That is our key ID. This is how we identify keys. We’re now ready to generate some sub keys that we can actually use.

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.
gpg: WARNING: server 'keyboxd' is older than us (2.4.3 < 2.4.5)
gpg: Note: Outdated servers may lack important security fixes.
gpg: Note: Use the command "gpgconf --kill all" to restart them.
gpg: WARNING: server 'keyboxd' is older than us (2.4.3 < 2.4.5)
gpg: Note: Outdated servers may lack important security fixes.
gpg: Note: Use the command "gpgconf --kill all" to restart them.
gpg: directory '/Users/mkrueger/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/Users/mkrueger/.gnupg/openpgp-revocs.d/64CFA56B02F7B2E484B09BE29F9F051089326E60.rev'
public and secret key created and signed.

pub   rsa4096 2024-05-01 [C]
      64CFA56B02F7B2E484B09BE29F9F051089326E60
uid                      Matthew Krueger (Matthew's Example Master Certifying Key for Website) <example@matthewkrueger.com>
  1. We can confirm our key is generated by checking our keyring. We do this by using the command gpg --list-keys. Here’s my keyring. If you notice, we’re missing a few things. Our key we just generated only has a C. But my real key has three keys label sub below, that each have an expiry date, as well as an S, E, and A. We’ll explore these sub-keys next.
pub   rsa4096 2024-05-01 [C]
      64CFA56B02F7B2E484B09BE29F9F051089326E60
uid           [ultimate] Matthew Krueger (Matthew's Example Master Certifying Key for Website) <example@matthewkrueger.com>

pub   rsa4096 2024-01-05 [C]
      E7444039BF585550BD8AA0F504A3D43F84760AC0
uid           [ultimate] Matthew Krueger (Matthew's Master Certifying Key) <contact@matthewkrueger.com>
sub   rsa4096 2024-01-05 [S] [expires: 2027-01-04]
sub   rsa4096 2024-01-05 [E] [expires: 2027-01-04]
sub   rsa4096 2024-01-05 [A] [expires: 2027-01-04]

# Generating Subkeys

  1. First, we’ll get our list of keys again. Use gpg --list-keys for this. Since we’re working on our example key, I’ll use my first selection, 64CFA56B02F7B2E484B09BE29F9F051089326E60. We can also use the last 16 digits of this key for short this is called the keyID. (There’s also a short keyID that’s the last 8 digits)

  2. Next, we’ll use the fingerprint to edit our key. You’ll need your Master key password at this point. Enter it when it prompts you. At this point, we’ll be in a terminal for GPG. We can ask it for help with help! gpg --expert --edit-key <your key> is the command we need for this operation.

sec  rsa4096/9F9F051089326E60
     created: 2024-05-01  expires: never       usage: C   
     trust: ultimate      validity: ultimate
[ultimate] (1). Matthew Krueger (Matthew's Example Master Certifying Key for Website) <example@matthewkrueger.com>

gpg> help

gpg> help
quit        quit this menu
save        save and quit
help        show this help
fpr         show key fingerprint
grip        show the keygrip
list        list key and user IDs
uid         select user ID N
key         select subkey N
check       check signatures
sign        sign selected user IDs [* see below for related commands]
lsign       sign selected user IDs locally
tsign       sign selected user IDs with a trust signature
nrsign      sign selected user IDs with a non-revocable signature
adduid      add a user ID
addphoto    add a photo ID
deluid      delete selected user IDs
addkey      add a subkey
addcardkey  add a key to a smartcard
keytocard   move a key to a smartcard
keytotpm    convert a key to TPM form using the local TPM
bkuptocard  move a backup key to a smartcard
delkey      delete selected subkeys
addrevoker  add a revocation key
addadsk     add an additional decryption subkey
delsig      delete signatures from the selected user IDs
expire      change the expiration date for the key or selected subkeys
primary     flag the selected user ID as primary
pref        list preferences (expert)
showpref    list preferences (verbose)
setpref     set preference list for the selected user IDs
keyserver   set the preferred keyserver URL for the selected user IDs
notation    set a notation for the selected user IDs
passwd      change the passphrase
trust       change the ownertrust
revsig      revoke signatures on the selected user IDs
revuid      revoke selected user IDs
revkey      revoke key or selected subkeys
enable      enable key
disable     disable key
showphoto   show selected photo IDs
clean       compact unusable user IDs and remove unusable signatures from key
minimize    compact unusable user IDs and remove all signatures from key

* The 'sign' command may be prefixed with an 'l' for local signatures (lsign),
  a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures
  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).

gpg>
  1. Now, that’s a lot of stuff. But what we’re mainly interested in is adding a subkey to this. If we check the help page, this is under the addkey command. Type that in, and then enter option 8 for an RSA subkey. This should look pretty similar, as we’re just repeating the process of generating a new key, and we’ll follow the same exact steps.
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)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card
Your selection?
  1. Follow the steps as above, toggling everything off but sign. You’ll notice the option for certify isn’t here. Only Master keys can certify. We’ll also want 4096 bit security. Expiry wise, these are more likely to be useful expiring after a year or so. I have mine set to expire after 3 years since I keep my keys on a FIPS hardware security key (something I’ll cover in a later post). I’d advise around a year. Make sure to set a password for this key as well. This is VITALLY important just as with the main key. Since this is a demo key, I am not going to be adding one here.

Possible actions for this RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection?

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 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) 1y
Key expires at Thu May  1 02:04:32 2025 EDT
Is this correct? (y/N) y
Really create? (y/N) y
  1. Repeat this process, toggling everything but encrypt on the second key, and everything but Authenticate on the third. After this is complete, you should see an output that looks like below. Type save to save the keys.
sec  rsa4096/9F9F051089326E60
     created: 2024-05-01  expires: never       usage: C   
     trust: ultimate      validity: ultimate
ssb  rsa4096/8D65232E2D447C4A
     created: 2024-05-01  expires: 2025-05-01  usage: SR  
ssb  rsa4096/F77E8401DB3453FB
     created: 2024-05-01  expires: 2025-05-01  usage: ER  
ssb  rsa4096/A63FDD38204FB63E
     created: 2024-05-01  expires: 2025-05-01  usage: AR  
[ultimate] (1). Matthew Krueger (Matthew's Example Master Certifying Key for Website) <example@matthewkrueger.com>
  1. Now we’re done! We have GPG keys in our keyring. We’ll talk about offloading these keys to physical security keys later, as well as talk about how to actually use the keys to do cool things like encrypting and decrypting messages. We’ll also upload our key to a keyserver.

While human written and reviewed, parts of this article were written with the assistance of Generative AI tools.

Last updated on May 01, 2024 02:17 UTC
Licensed under GPL, using entirely Free Software (sans hosting). See GitLab for more.
Built with Hugo
Theme Stack designed by Jimmy