Software Development, english

OpenPGP On The Job – Part 4: Generating Keys

Patience is key! Having survived theoretical basics, an excursus in verification and a secure setup guide, we now can finally dive into the real thing: Generating all new and shiny PGP keys! Unfortunately the devil is all in the details: Keys may be very different. Are there any anonymous keys? The longer, the better, right? Find all the answers below.

computer-laptop-mail-verschlüsselung


Revoking Keys

It is not possible to remove a public key from a key server. This becomes exceptionally annoying in case you can't use your key anymore or it got broken (compromised).

In both cases a new key would have to be uploaded. But how should other users know which key is the right one? Due to this, there is a simple rule: Have one key and one key only available for the public. Do use only this key.

In case of snafu it is possible to revoke the old key before a new key gets uploaded. A revoked key will be flagged accordingly. Over time a couple of revoked keys will exist but there must always be only one non revoked key.

Revoking a key has a downside: All data signed or encrypted with this key does also get revoked, i. e. may not be trustworthy anymore. This is especially true for signatures for keys of other participants. This weakens the web of trust created by mutual key signing.

Masterkey And Subkeys

To decrease the impact of such effects, the OpenPGP standard includes so called subkeys. With subkeys it is possible to assign the tasks sign, encrypt and authenticate to exactly one subkey respectively. Subkeys are connected to their master key by technical means and can't exist without it. The master key alone will take care of the important task certify.

Why does this make things better? Well, the trick is that for daily use only the subkeys are required. The master key is not required to exist in the keyring for signing and encrypting operations. This makes it possible to store it securely e. g. on an USB flash drive.

An attacker does now need to break more key in order to compromise signatures and encryption. In addition, subkeys can be revoked individually. This decreases the risk of a completely compromised correspondence. A revoked subkey may be replaced by a new one without having to revoke and replace the master key or the other subkeys.

Generating The Masterkey

Due to those reasons, we are going to generate a masterkey with three subkeys. I'll base my work on the very good article The Almost Perfect Key Pair. Ok, let's do this:

Key Algorithm

# Generate master key with all custom options activated
gpg --expert --full-gen-key
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (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 and ECC
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key


In order to start, we need to select a crypto algorithm for our new key. Wait a minute! Doesn't public key cryptography not always use RSA? Well, not quite! Virtually all known asymmetric crypto algorithms may be valid here. The standard itself describes the well known RSA as well as DSA and Elgamal. Despite being considered optional OpenPGP does also support ECC, the Elliptic Curve Cryptography.

The last one tends to get more and more recommended from a security point of view. Unfortunately ECC support is currently not very wide spread, so there is a high chance of other people not being able to use your public key if that was chosen.

We are going to use option 8 (RSA), because:

  1. It is widely spread and mature, so a maximum of compatibility is provided.
  2. Security token like the Yubikey do currently mainly support RSA only.

Let's continue:

Key Actions

Your selection? 8

Possible actions for a 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


This is the important step. We are going to remove all actions for this key, except for Certify. This makes the master key usable for this action only while leaving the others for the subkeys.

So let's chose:

Current allowed actions: Sign Certify Encrypt

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

Your selection? s

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify Encrypt

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

Your selection? e

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify

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

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)


Keysize

The crucial RSA question. In general it is true: The longer, the better. But be aware: When comparing different crypto algorithms, longer does not necessarily mean better. This is because different algorithms require keys of different lengths. AES is good with 256 bit, DSA is said to be reasonably secure with 1024 bit, etc.

The security of RSA is based on the assumption that prime factorization of a large number is very hard in a reasonable amount of time. The keysize does directly impact the length of this number and thereby also directly impact the security of the system.

So let's just choose 4096 bit then and we are done for, are we? The choice of key length does also depend on how you are going to use the keys in the future. If for example you are planning on using the keys on a security token such as an OpenPGP card, the supported key length may be limited due to hardware limitations.

The Yubico-Blog goes into this in great detail but is also easy to understand. The bottom line is:

  1. 2048 bit ought to be reasonably secure until 2030.
  2. 4096 bit do yield an exponential increase in security but do also double the memory and CPU consumption. In relation with the first point, usage of large keys must be part of an economical assessment.
  3. RSA keys get replaced every few years, so the choice of keysize is not an eternal one.
  4. Security hardware, e. g. the Yubikey NEO, may be limited to keysizes less than 4096 bit due to reduced hardware capabilities.
  5. The usage of unreasonably large keys on embedded devices increases battery consumption and CPU time to probably unacceptable values.

Due to those reasons, we are going to choose 4096 bit for the master key. It will not be used on a daily basis and will not be stored on security hardware. The subkeys however are going to be 2048 bit long. This provides the best trade off between security and resource consumption on embedded hardware. This enables us to store the generated subkeys on an OpenPGP card, such as a Yubikey NEO. If you are not planning on doing so, you could of course just go ahead and choose 4096 bit as key length of the subkeys.

Update 2018 Sep.: In the meantime, Yubico has released series 5 of the YubiKey. The NEO is now called YubiKey 5 NFC and does support RSA 4096. If you are planning on using your keys on such a device, you may choose 4096 bit key length for the subkeys. The theoretical disadvantages of a longer key are stoll valid. However, in praxis those disadvantages tend to be small enough to remain unnoticed.


Expiration

What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years


In addition to revoking a key, there is also a second mechanism to secure keys from fraud: Automatic key expiration. Keys may be marked outdated (expired) after a certain amount of time, ranging from days to years. Signatures and encrypted documents created after a key has expired must not be trusted. Apps like Enigmail will present an appropriate warning. The expiration date can be changed by the owner of the key for as long as she has control over it. This is why an expired key is untrustworthy: It is unsure if the owner still has control over it.

The choice for the expiration period is once again a trade-off between security and convenience. Short periods must be updated too often. Long periods tend to present too much of an attack opportunity.

My personal choice is one year.


Set The User ID

Key is valid for? (0) 1y
Key expires at 06/25/19 11:36:56 Mitteleuropäische Sommerzeit
Is this correct? (y/N) y

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

Real name: Jan Mosig
Email address: jan.mosig@itemis.de
Comment:
You selected this USER-ID:
    "Jan Mosig <jan.mosig@itemis.de>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o


Every key is bound to a USER-ID. This is a name and an e-mail-adress. It is not required that name and address do match or even exist. This allows to create "official" keys as well as anonymous ones.

The downside is that it is also possible to pose as someone else. This is the reason why it is important to verify imported keys for validity and trustworthiness, e. g. by checking key signatures or just asking the owner for the ID of her key.

One last thing is missing:


Passphrase

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.


Before key generation starts, a passphrase must be entered. This is a sort of a password that will be used to encrypt the private key. Without the passphrase, you cannot use the private key, hence cannot decrypt, sign or even modify, export or delete the key. The passphrase is also applied to the subkeys.

In general the usual best practices for choosing do also apply to passphrases. But keep in mind: A good password does not necessarily be hard to remember, nor is it required to use a random sequence of (special) characters and numbers. It just needs to be sufficiently long. That's why it is called a passphrase and not password.


Result

You'll get:

gpg: key 0x3D5C6DBB1C061833 marked as ultimately trusted
gpg: revocation certificate stored as 'C:/Users/mosig_user/.gnupg/openpgp-revocs.d\A3C1B44DEC45C33488A6C4C03D5C6DBB1C061833.rev'
public and secret key created and signed.

pub   rsa4096/0x3D5C6DBB1C061833 2018-06-25 [C] [expires: 2019-06-25]
      Key fingerprint = A3C1 B44D EC45 C334 88A6  C4C0 3D5C 6DBB 1C06 1833
uid                              Jan Mosig <jan.mosig@itemis.de>

  • Since the key is our own, it is ultimately trusted by default.
  • The file A3C1B44DEC45C33488A6C4C03D5C6DBB1C061833.rev contains a so called revocation certificate. A key is revoked by importing this file into the keyring. A key cannot be revoked without the certificate, so don't lose it. However, it may be regenerated with the gpg client for as long as you have access to your private key.
  • The key does also have a name, the so called (long) ID: 0x3D5C6DBB1C061833.
  • Some crypto tasks may need the key fingerprint. This is just a hash code of the whole 4096bit long key: A3C1 B44D EC45 C334 88A6  C4C0 3D5C 6DBB 1C06 1833.

This will give us a nice master key. Let's continue with the subkeys.

Generating Subkeys

Since the masterkey has only been enabled for the certify task, we need one subkey for every crypto task left respectively:

  1. Encrypt
  2. Sign
  3. Autenticate

Once a maskterkey has been created, subkeys may be added via gpg's edit shell:

gpg --expert --edit-key 3D5C6DBB1C061833
gpg (GnuPG) 2.2.7; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/0x3D5C6DBB1C061833
     created: 2018-06-25  expires: 2019-06-25  usage: C
     trust: ultimate      validity: ultimate
[ultimate] (1). Jan Mosig <jan.mosig@itemis.de>

gpg>


The gpg-shell is sort of a subconsole of your OS's console. You can view available commands with We are going to chose addkey. This will start a key generation process very much like that of the masterkey:

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
Your selection? 8

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

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


Of course, we are going to select the crypto algorithm of the masterkey (RSA) which brings us to the key actions selection. Every key must be assigned one action and one action only. Entering S toggles the action sign, etc. For the first key, we are going to leave only encrypt selected:

Your selection? s

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

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

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 1y
Key expires at 06/25/19 12:37:37 Mitteleuropõische Sommerzeit
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.

sec  rsa4096/0x3D5C6DBB1C061833
     created: 2018-06-25  expires: 2019-06-25  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa2048/
     created: 2018-06-25  expires: 2019-06-25  usage: E
[ultimate] (1). Jan Mosig <jan.mosig@itemis.de>


The other attributes of the key will be exactly like those of the masterkey except for the keysize. Due to the described reasons, we will choose 2048 bit here. This gets us a subkey with ID 0xAB69A2DFCB50B517 that can be used for encryption only.

If we repeat the process for two more times and choose sign and authenticate respectively, we will get:

sec  rsa4096/0x3D5C6DBB1C061833
     created: 2018-06-25  expires: 2019-06-25  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa2048/0xAB69A2DFCB50B517
     created: 2018-06-25  expires: 2019-06-25  usage: E
ssb  rsa2048/0xC5CED131C6D9CF8C
     created: 2018-06-25  expires: 2019-06-25  usage: S
ssb  rsa2048/0xB65305FC2E9BBE54
     created: 2018-06-25  expires: 2019-06-25  usage: A
[ultimate] (1). Jan Mosig <jan.mosig@itemis.de>

gpg> save #Store and quit


This completes our key setup. The keys can now be used for the tasks of your choice. However, there is one thing left to do which will significantly increase security.

Create A Backup

At the moment, the keys do only exist in your private keyring. If you lose it or it gets corrupt, the keys and all data encrypted with them is gone for good. This is the reason why you should always create a backup and store it in a secure place (doesn't make much sense to store the backup right beside your keys if your device gets stolen, doesn't it).

In general it would be sufficient to just backup gpg's home directory. However, we are going to export the keys individually. This will leave us with less bloat and is a very flexible solution, e. g. those keys may be imported on another device.

This is how it works:

# Generate backup copy of revocation certificate
gpg --output 3D5C6DBB1C061833.rev --gen-revoke 3D5C6DBB1C061833
# Export public master key
gpg --export --armor 3D5C6DBB1C061833 > 3D5C6DBB1C061833.pub.asc
# Export private master key
gpg --export-secret-keys --armor 3D5C6DBB1C061833 > 3D5C6DBB1C061833.priv.asc
# Export private subkeys. There are no public subkeys.
gpg --export-secret-subkeys --armor 3D5C6DBB1C061833 > 3D5C6DBB1C061833.sub_priv.asc

This will result in four files which may be stored in an encrypted zip file which lives on a USB flash drive.

Remove Masterkey

Now that we've got a backup, we may go even further: Remove the masterkey from the keyring. Advantage: It cannot be compromised that easily by hacking into your device. Downsize: All operations based on certification (e. g. signing other people's keys) will require a reimport of the key (along with removal of the key after use). Fortunately certify based operations are not that common during daily work. Once you have signed all the keys of your daily contacts, it tends to become a rare operation.

The following procedure removes the masterkey from the keyring. Important: Without a previous backup of masterkey and subkeys, they will be gone for good!

# Delete master and sub keys, will request one approval per key (4 approvals total).
gpg --delete-secret-key 3D5C6DBB1C061833
gpg (GnuPG) 2.2.7; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


sec  rsa4096/0x3D5C6DBB1C061833 2018-06-25 Jan Mosig <jan.mosig@itemis.de>

Delete this key from the keyring? (y/N) y
This is a secret key! - really delete? (y/N) y

# Now reimport the subkeys only
gpg --import 3D5C6DBB1C061833.sub_priv.asc
gpg: key 0x3D5C6DBB1C061833: "Jan Mosig <jan.mosig@itemis.de>" not changed
gpg: To migrate 'secring.gpg', with each smartcard, run: gpg --card-status
gpg: key 0x3D5C6DBB1C061833: secret key imported
gpg: Total number processed: 1
gpg:              unchanged: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1


If we now go ahead and have a look at the private keyring, we can verify that it worked.

Inspecting The Keyring

As described in part one, PGP keys do always come in pairs: Public key and private key. All keys are stored in a keyring. This ring also has two parts: One for all known public keys (including your own) and one for your private keys. This is how you can have a look at those on the console:

# View public key ring
gpg --list-keys
# Or short version
gpg -k # lower k
# View private key ring
gpg --list-secret-keys
# Or short version
gpg -K # Capital K

The private keyring we just created should look like this:

gpg -K
C:/Users/mosig_user/.gnupg/pubring.kbx
--------------------------------------
sec#  rsa4096/0x3D5C6DBB1C061833 2018-06-25 [C] [expires: 2019-06-25]
      Key fingerprint = A3C1 B44D EC45 C334 88A6  C4C0 3D5C 6DBB 1C06 1833
uid                   [ultimate] Jan Mosig <jan.mosig@itemis.de>
ssb   rsa2048/0xAB69A2DFCB50B517 2018-06-25 [E] [expires: 2019-06-25]
ssb   rsa2048/0xC5CED131C6D9CF8C 2018-06-25 [S] [expires: 2019-06-25]
ssb   rsa2048/0xB65305FC2E9BBE54 2018-06-25 [A] [expires: 2019-06-25]


Perfect! This is how its supposed to look like. The key at the top (sec) is the masterkey with 4096 bit. Below there are the three subkeys (ssbwith 2048 bit each, one for Encrypt, Sign and Authenticate respectively.

That's it, as for the key generation, we are done. The keys are ready to be used for your daily crypto tasks. gpg will choose the appropriate key for a task automatically.

The next part of the series will concentrate on using those keys for e-mail purposes with Thunderbird and Enigmail.

    
About Jan Mosig

Jan Mosig works for itemis in Leipzig. He is focussed on solving problems in his daily project routine and relies on technical software quality, Agile and the courage to change.