Skip to content

Instantly share code, notes, and snippets.

@rlan
Forked from gnzsnz/Creating GPG keys and subkeys.md
Last active February 1, 2025 18:07
Show Gist options
  • Save rlan/6d9e2bb1c9051cd3a4237dbdbbd02b98 to your computer and use it in GitHub Desktop.
Save rlan/6d9e2bb1c9051cd3a4237dbdbbd02b98 to your computer and use it in GitHub Desktop.
Creating GPG keys and subkeys

Creating GPG keys and subkeys

There are the steps to create GPG key pair and the additional steps to create a subkey.

Create GPG keys

gpg --full-generate-key
Please select what kind of key you want:
   (1) RSA and RSA
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (9) ECC (sign and encrypt) *default*
  (10) ECC (sign only)
  (14) Existing key from card
Your selection? 9

Please select which elliptic curve you want:
   (1) Curve 25519 *default*
   (4) NIST P-384
   (6) Brainpool P-256
Your selection? 1

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

Create subkey

Once have a key pair we can create a subkey

gpg --edit-key 6BA43BDD3E73CD57855B9D77DEDE5447A7ABB295

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)
  (10) ECC (sign only)
  (12) ECC (encrypt only)
  (14) Existing key from card
Your selection? 10
Please select which elliptic curve you want:
   (1) Curve 25519 *default*
   (4) NIST P-384
   (6) Brainpool P-256
Your selection? 1
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) 0

gpg> save

Repeat above for each machine to have their own, different signing key.

Export keys for offline backup:

gpg --output public.gpg.txt --armor --export 6BA43BDD3E73CD57855B9D77DEDE5447A7ABB294
gpg --output secret.gpg.txt --armor --export-secret-keys 6BA43BDD3E73CD57855B9D77DEDE5447A7ABB294

Get subkey ID's.

gpg --list-secret-keys --keyid-format=long

sec   ed25519/xyz 2025-01-01 [SC]
      6BA43BDD3E73CD57855B9D77DEDE5447A7ABB294
uid                 [ unknown] Name <[email protected]>
ssb   cv25519/abc 2025-01-01 [E]
ssb   ed25519/def 2025-01-01 [S]
ssb   ed25519/ghi 2025-01-01 [S]

Generate one signing subkey for each machine. Note the exclaimation mark after the ID.

gpg --output machine1.gpg.txt --armor --export-secret-subkeys def!
gpg --output machine2.gpg.txt --armor --export-secret-subkeys ghi!

Delete the primary key.

gpg --delete-secret-keys 6BA43BDD3E73CD57855B9D77DEDE5447A7ABB294
gpg --delete-keys 6BA43BDD3E73CD57855B9D77DEDE5447A7ABB294

Finally import the subkey

gpg --import machine1.gpg.txt

Verify

gpg --list-secret-keys --keyid-format=long

sec#  ed25519/xyz 2025-01-01 [SC]
      6BA43BDD3E73CD57855B9D77DEDE5447A7ABB294
uid                 [ unknown] Name <[email protected]>
ssb   ed25519/def 2025-01-01 [S]

The sec# means a subkey is loaded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment