Create a GPG key

8 minute read

From the official GPG website:

GnuPG is a complete and free implementation of the OpenPGP standard as defined by RFC4880 (also known as PGP). GnuPG allows to encrypt and sign your data and communication, features a versatile key management system as well as access modules for all kinds of public key directories. GnuPG, also known as GPG, is a command line tool with features for easy integration with other applications.

Create your keys on an air-gapped system.

There is a special post explaining how to create an air-gapped raspberry pi that you should follow before creating your keys.

Install required software

The following software will be necessary to generate the GPG key and back it up.

$ sudo apt-get install -y gnupg2 gnupg-agent pinentry-curses scdaemon pcscd yubikey-personalization libusb-1.0-0-dev paperkey zbar-tools

Creating the master key

Create a temporary working directory

Create a directory in /tmp which won’t survive a reboot.

$ export GNUPGHOME=$(mktemp -d) ; echo $GNUPGHOME

Create the configuration

$ cat << EOF > $GNUPGHOME/gpg.conf
use-agent
personal-cipher-preferences AES256 AES192 AES CAST5
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
cert-digest-algo SHA512
s2k-digest-algo SHA512
s2k-cipher-algo AES256
charset utf-8
fixed-list-mode
no-comments
no-emit-version
keyid-format 0xlong
list-options show-uid-validity
verify-options show-uid-validity
with-fingerprint
EOF

Create the master key

gpg2 --full-gen-key

Use the following parameters to create your key:

  • RSA (sign only)
  • 4096 bits
  • Valid for 2y
  • Name Surname
  • email address (used to export the keys)
  • strong passphrase
Output
gpg: /tmp/keyCreation/trustdb.gpg: trustdb created
gpg: key 0x45B2745200A5D6B1 marked as ultimately trusted
gpg: directory '/tmp/keyCreation/openpgp-revocs.d' created
gpg: revocation certificate stored as '/tmp/keyCreation/openpgp-revocs.d/0B9139BF0D9F3C96F5059B3045B2745200A5D6B1.rev'
public and secret key created and signed.

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 2020-10-02
Note that this key cannot be used for encryption.  You may want to use
the command "--edit-key" to generate a subkey for this purpose.
pub   rsa4096/0x45B2745200A5D6B1 2017-10-03 [S] [expires: 2020-10-02]
      Key fingerprint = 0B91 39BF 0D9F 3C96 F505  9B30 45B2 7452 00A5 D6B1
uid                   [ultimate] John Doe <johndoe@mail.com>

The following files are created:

  • openpgp-revocs.d : This is the directory where gpg stores pre-generated revocation certificates. The file name corresponds to the OpenPGP fingerprint of the respective key. It is suggested to backup those certificates and if the primary private key is not stored on the disk to move them to an external storage device. Anyone who can access theses files is able to revoke the corresponding key. You may want to print them out. You should backup all files in this directory and take care to keep this backup closed away.
  • private-keys-v1.d : This folder holds all the private keys. It was initially used only by gpgsm (for S/MIME keys), but since GnuPG 2.1 it is also used by gpg (for OpenPGP keys). The “v1” part in the name has nothing to do with the version of GnuPG.
  • pubring.kbx : The public keyring using a different format. This file is shared with gpgsm. You should backup this file.
  • S.gpg-agent : a socket for the gpg-agent
  • trustdb.gpg : The trust database. There is no need to backup this file; it is better to backup the ownertrust values (see option –export-ownertrust).

Save the key id:

$ KEYID=0x4F0D71D6CBFE47E4

At this stage it is recommended that you backup your master key.

Create your GPG subkeys

In this section we will edit our GPG key to add 3 subkeys :

  • one to Sign
  • one to Encrypt
  • one to Authenticate

But first, a word on subkeys from the debian wiki:

OpenPGP further supports subkeys, which are like the normal keys, except they’re bound to a master key pair. A subkey can be used for signing or for encryption. The really useful part of subkeys is that they can be revoked independently of the master keys, and also stored separately from them.

In other words, subkeys are like a separate key pair, but automatically associated with your main key pair.

Start editing your master key

gpg2 --expert --edit-key $KEYID
# Output
Secret key is available.

sec  rsa4096/0x45B2745200A5D6B1
     created: 2017-10-03  expires: 2020-10-02  usage: SC  
     trust: ultimate      validity: ultimate
[ultimate] (1). John Doe <johndoe@mail.com>

Create a signing key

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? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 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) 3y
Key expires at Sat 03 Oct 2020 05:08:26 AM CEST
Is this correct? (y/N) y
Really create? (y/N) y

# Here you are asked to create a password to protect this signing key
# If putting this on a Nitrokey or Yubico, you might need to leave it unprotected

# Then you are prompted for the master key password to validate the changes

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/0x45B2745200A5D6B1
     created: 2017-10-03  expires: 2020-10-02  usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa2048/0xB535D105B7288D1E
     created: 2017-10-04  expires: 2020-10-03  usage: S   
[ultimate] (1). John Doe <johndoe@mail.com>

Create an encryption key

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? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 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) 3y
Key expires at Sat 03 Oct 2020 05:09:18 AM CEST
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/0x45B2745200A5D6B1
     created: 2017-10-03  expires: 2020-10-02  usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa2048/0xB535D105B7288D1E
     created: 2017-10-04  expires: 2020-10-03  usage: S   
ssb  rsa2048/0x688FD21F9EF4ECD1
     created: 2017-10-04  expires: 2020-10-03  usage: E   
[ultimate] (1). John Doe <johndoe@mail.com>

Create an authentication key

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

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? E

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

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

Your selection? A

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

   (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)
Requested keysize is 2048 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) 3y
Key expires at Sat 03 Oct 2020 05:10:25 AM CEST
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/0x45B2745200A5D6B1
     created: 2017-10-03  expires: 2020-10-02  usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa2048/0xB535D105B7288D1E
     created: 2017-10-04  expires: 2020-10-03  usage: S   
ssb  rsa2048/0x688FD21F9EF4ECD1
     created: 2017-10-04  expires: 2020-10-03  usage: E   
ssb  rsa2048/0x90390987B3B61E02
     created: 2017-10-04  expires: 2020-10-03  usage: A   
[ultimate] (1). John Doe <johndoe@mail.com>

Save your work

gpg> save

Backup

Now that you have your subkeys, you can back them up the same way you backed up your master key. Use gpg2 --export-secret-subkeys johndoe@mail.com to get an export of your subkeys.

Sources