How to generate subkeys for Git and Mail, store the master key securely and how to avoid a disater. Use and configure GPG like a PRO.

Use the --home=path/to/home command-line argument or use export GNUPGHOME=path/to/home.

Getting started

  • Install
    • linux: gpg
    • Windows: Git for Windows (with all tools!) or GPG4Win
  • Perform every action on the MASTERKEY on the USB drive by setting home accordingly.
  • Never copy the private MASTERKEY off the drive. Only exception: Backup-drive or printing the key.

Generating a master key

keep this key offline!

  • This key is only used for key-generation.
  • Keep it on a USB drive, and/or print it.


gpg --home=path/to/home --default-new-key-algo rsa4096 --gen-key
# List generated keys
gpg --home=path/to/home --list-secret-keys --keyid-format LONG
# Copy the part after rsa4096/
# Masterkey should not expire. When using --generate-full-key
# This is asked by prompt. --gen-key does not
gpg --home=path/to/home --edit-key MASTERKEYID
# gpg> expire
# choose 0
# gpg> save
  • Choose a strong password. Store it in a safe place!

Add identities (uids)

(e.g. if you are using multiple mail addresses)

gpg --edit-key MASTERKEYID
# gpg> adduid
# Real Name: <name>
# Email address: <email>
# Comment: <comment or Return to none>
# Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
# Enter passphrase: <password>
# gpg> uid <uid>
# gpg> trust
# Your decision? 5
# Do you really want to set this key to ultimate trust? (y/N) y
# gpg> save

# Make a uid the primary uid
# gpg> uid <uid>
# gpg> primary

Generating a sub-key for signing/encryption

  • Those keys are used for Mail/Git/…
gpg --home=path/to/home --edit-key MASTERKEYID
# gpg> addkey
# Sign only (for git)
# Enter Keyphrase
# Choose 4096
# Choose expiry date. e.g. 2 Years
# gpg> save

# Export (do not miss the !). Use --armor for ascii format
# Get the SUBKEYID with --edit-key MASTERKEYID list
gpg --home=path/to/home --export-secret-subkeys SUBKEYID! (SUBKEYID2! ...) > subkey.key
# Export all subkeys (not recommended)
gpg --home=path/to/home --export-secret-subkeys MASTERKEYID > subkey.key

Debian Wiki: One might be tempted to have one sub-key per machine so that you only need to exchange the potentially compromised sub-key of that machine. In case of a single sub-key used on all machines, it needs to be exchanged on all machines [when that single sub-key is or suspected to be compromised].

→ Use one sub-key per machine only for signing and NOT for encryption. Or use one sub-key across multiple machines.

Import Key

gpg --import subkey.key
# Change Password and trust
gpg --edit-key MASTERKEYID 
# gpg> passwd
# gpg> trust
# choose ultimate (5)
# gpg> save

# Note: password on usb drive keeps unchanged!

From Debian Wiki: If you imported the private master key:

If you are using GnuPG 2.1 or later, all you have to do is to delete the file $HOME/.gnupg/private-keys-v1.d/KEYGRIP.key, where KEYGRIP is the "keygrip" of the master key which can be found by running gpg --with-keygrip --list-key YOURMASTERKEYID. (The private part of each key pair has a keygrip, hence this command lists one keygrip for the master key and one for each subkey.) Note however that if the keyring has just been migrated to the new format, then the now obsolete $HOME/.gnupg/secring.gpg file might still contain the private master key: thus be sure to delete that file too if it is not empty.

Verify that the private master-key is not present:

gpg -K
# sec# instead of sec indicates that the private key is not really there, that is what we want!

Send key to key-server

gpg --home=path/to/home --keyserver --send-keys MASTERKEYID

Configure Git

gpg --edit-key MASTERKEYID list
# Copy the part after ssb rsa4096/
git config --global user.signingkey SUBKEYID
git config --global commit.gpgsign true
gpg --export --armor SUBKEYID
# Copy public key and add to Github/Gitlab config

# If you are using GPG4Win you may want to configure git to use GPG4Win instead
git config --global gpg.program "c:/Program Files (x86)/GnuPG/bin/gpg.exe"

Cache password

Add a file gpg-agent.conf at ~/.gnupg or %APPDATA%/gnupg (GPG4Win). Add the content:

default-cache-ttl 7200
max-cache-ttl 7200

If you are using Git for Windows gpg-agent may not automatically start. If this is the case, create a task which executes gpgconf --launch gpg-agent.



From Debian Wiki: If disaster strikes, and you need to revoke the sub-key for whatever reason, do the following:

  1. Mount the encrypted USB drive.
  2. gpg --home=path/to/home --edit-key MASTERKEYID

At the gpg> prompt, list the keys (list), select the unwanted one (key 123), and generate a revocation certificate revkey, then save. Send the updated key to the key-servers as above.


From Cédric Félizard: This is particularly useful if this email address is no longer yours for some reason.

Unless you’ve never published your key to a public server (unlikely!), you can’t delete an email address from your GPG key, but you can revoke it.

gpg --home=path/to/home --edit-key MASTERKEYID
# gpg> uid <uidtorevoke>
# gpg> revuid
# gpg> save

! Do not forget to re-send the keys to the key-servers and re-export/import the sub-keys.