Install and Configure GnuPG
This page will cover installing and configuring the GnuPG software.
Install GnuPG
macOS
Only one GnuPG
A lot of the problems I've seen people have with using GnuPG on macOS are caused by having multiple GnuPG programs installed on the machine at the same time.
I normally use Homebrew (see below) on every machine, and some of the packages I normally install have gnupg
as a dependency. Homebrew usually ends up installing it anyway, so I have found it easier to just install GnuPG via Homebrew.
The most common "other" GnuPG installation is GPGTools (also knows as "MacGPG", "MacPGP", etc.) This distribution includes some GUI tools for managing keyrings, a System Preferences widget to configure the gpg
command, and a non-free plug-in which handles PGP operations within Mail.app (to make it easier to send and received signed and encrypted emails).
The problems people have with multiple instances of gpg
are usually caused by the directories in PATH
being in different orders for different processes. Even if you've taken the time to lovingly hand-craft your free-range organic .bashrc
(or .zshrc
) file so it always puts the directories in a certain order, the fact is that not every process on the machine is going to use the shell-rc files from your home directory.
The only way I've found to ensure that every process on the machine uses the same gpg
program, is to make sure the machine only has one gpg
program to begin with.
The directions in this book were written using GnuPG installed by Homebrew. They will probably work with the GPGTools version of gpg
, however I haven't tried it myself - I haven't used GPGTools in several years (i.e. since I discovered Homebrew).
If you already have GPGTools installed and want to use the Homebrew version instead, start by using the directions on this page to uninstall GPGTools.
Uninstalling GPGTools will not affect the contents of your keyring files, although you may have to go through the config files in your $HOME/.gnupg/
directory and change a few paths after installing the Homebrew packages (this is covered below).
Homebrew
Homebrew describes itself as "The Missing Package Manager for macOS", and IMHO this is a pretty accurate statement. It provides a way to easily install most of the open-source packages commonly available for Linux, using a command line interface similar to the yum
, apt
, or pacman
commands you would have on a Linux system.
I usually end up needing Homebrew on every macOS machine anyway, so I've gotten into the habit of just installing it on all of my machines.
Homebrew's web site has directions for how to install it. (It's easy, just copy and paste one command from the web page into your shell.)
⇒ Homebrew
Check your PATH
Once Homebrew is installed, open a new Terminal window and make sure the directory where Homebrew installs things, is listed in your PATH
. This will normally be /usr/local/bin
for Intel machines, or /opt/homebrew/bin
for ARM (Apple Silicon) machines.
$ which brew
/opt/homebrew/bin/brew
$ echo "$PATH" | tr : '\n' | grep $( brew --prefix )
/opt/homebrew/bin
If you find that you need to update your .bashrc
or .zshrc
file to make sure the Homebrew path is in the right order, now is the time to do that.
Install gnupg
and pinentry-mac
Once Homebrew is installed, this command will install GnuPG and the "PIN entry" program you'll need in order to securely enter passphrases under macOS.
brew install gnupg pinentry-mac
Once it's installed, you can run "gpg --version
" to see what version you're running.
(jms1@jms1Air) 29 ~ $ gpg --version
gpg (GnuPG) 2.4.0
libgcrypt 1.10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /Users/jms1/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
Linux - Debian 11
This command will install GnuPG. Once of its dependencies will be pinentry-curses
, which provides a "PIN entry" program that uses a terminal window to prompt you for passphrases.
apt install gnupg2
Once it's installed, you can run "gpg --version
" to see what version you're running.
root@a4a47a903855:/# gpg --version
gpg (GnuPG) 2.2.27
libgcrypt 1.8.8
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /root/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
Note that the terminal-mode pinentry program requires you to set up a GPG_TTY
environment variable, so that it knows where to show the prompt. You may want to add the following to your .bashrc
file.
export GPG_TTY=$( tty )
gpg-connect-agent updatestartuptty /bye > /dev/null
Linux - CentOS 7
CentOS 7 normally installs GnuPG2 on every machine. You can verify whether it's already installed or not ...
[root@0e0ef5dcbfcf /]# rpm -q gnupg2 pinentry
gnupg2-2.0.22-5.el7_5.aarch64
pinentry-0.8.1-17.el7.aarch64
If it isn't installed, you can run this to install it.
yum install gnupg2 pinentry
Once it's installed, you can run "gpg --version
" to see what version you're running.
[root@0e0ef5dcbfcf /]# gpg --version
gpg (GnuPG) 2.0.22
libgcrypt 1.5.3
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: ~/.gnupg
Supported algorithms:
Pubkey: RSA, ?, ?, ELG, DSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
ℹ️ The GnuPG version in the CentOS 7 repos is rather old.
Some of the configuration options mentioned below may not work.
As with Debian, the terminal-mode pinentry program requires you to set up a GPG_TTY
environment variable, so that it knows where to show the prompt. You may want to add the following to your .bashrc
file.
export GPG_TTY=$( tty )
gpg-connect-agent updatestartuptty /bye > /dev/null
Configure GnuPG
The GnuPG software is configured using files in each user's $HOME/.gnupg/
directory. There are two ways to update these files: using the gpgconf
command, and manually editing the files.
In many versions of GnuPG, the gpgconf
command doesn't recognize many of the options that can exist in the config files, so I normally edit the files by hand.
$HOME/.gnupg/gpg.conf
This file configures the gpg
command itself.
Configure a default signing key
If you already have one or more PGP keys, once they're imported into your keyring you can choose one to be the default key, which will automatically be used when creating signatures.
This option normally uses a Key ID, however it can also take a name, as long as the name is unique within your keyring.
default-key E3F7F5F76640299C5507FBAA49B9FD3BB4422EBB
Disable copyright message
Some gpg
commands print a copyright message when they start. This option disables that notice.
no-greeting
Key ID display
-
This option will make
gpg
commands which show keys, show the full key fingerprints of the primary and sub-keys.with-subkey-fingerprint
-
This option will make
gpg
commands not include a shortened version of the fingerprint when printing the algorithm (i.e.rsa4096
instead ofrsa4096/B4422EBB
).keyid-format none
Together, they make the output look like this:
$ curl -s https://jms1.pub/jms1.pub.asc | gpg --show-key
pub rsa4096 2019-03-21 [SC] [expires: 2024-01-01]
E3F7F5F76640299C5507FBAA49B9FD3BB4422EBB
uid John Simpson <jms1@jms1.net>
uid John Simpson <kg4zow@mac.com>
uid John Simpson <kg4zow@kg4zow.us>
sub rsa4096 2019-03-21 [E] [expires: 2024-01-01]
3C8EC9C7B067A4C542F9727D795C2CF824364755
sub rsa4096 2019-03-21 [S] [expires: 2024-01-01]
77DEBB0C8C7FBAFF1E0E70DCE9E44ED30E2F2445
sub rsa4096 2019-03-21 [A] [expires: 2024-01-01]
7A6B95B6BF897A6497165AE436823233F8D09EB7
$HOME/.gnupg/gpg-agent.conf
Configure the "PIN entry" program
When gpg-agent
needs to read a secret key from the keyring, it will need to ask the user to enter their passphrase. It does this by running a "PIN entry" program. There are different "PIN entry" programs out there - some work by opening a GUI dialog, some work by clearing the terminal window and "drawing" what looks like a dialog, and others may use other methods.
You need to configure gpg-agent
and tell it what program to use to ask the user for the key's passphrase.
macOS - Homebrew
To use the pinentry-mac
program installed by Homebrew, first find the full path to the pinentry-mac
program ...
$ which -a pinentry-mac
/opt/homebrew/bin/pinentry-mac
Then edit (or create) the gpg-agent.conf
file and add this line:
pinentry-program /opt/homebrew/bin/pinentry-mac
Configure secret key retention time
GnuPG uses a program called gpg-agent
to hold secret keys in memory for a certain length of time. This means if you're going to be executing multiple gpg
commands which require the same key, you won't have to enter the key's passphrase over and over again.
You can configure how long gpg-agent
will remember the keys before deleting them from memory. (The values are in seconds.)
-
default-cache-ttl
= how long keys will be held in memory before being removed. Every time a key is used, the key's "timer" is reset. Default is 600 (ten minutes). I normally use 10-30 seconds. -
max-cache-ttl
= maximum length of time that any key will be held in memory, even if it has been used recently. Default is 7200 (two hours).
default-cache-ttl 30
max-cache-ttl 30
ℹ️ These settings only affect secret keys read from the disk.
Secret keys stored in a YubiKey are never sent to the computer, so
gpg-agent
cannot hold them in memory.
Configure the SSH agent
The gpg-agent
program can "speak the same language" as ssh-agent
.
Add this option to enable support for SSH.
enable-ssh-support
When gpg-agent
is working with SSH secret keys, it can also hold them in memory for a certain length of time, like it does with PGP keys. You can configure how long it holds these keys using these options. (These values are also in seconds.)
-
default-cache-ttl-ssh
= how long SSH keys will be held in memory before being removed. Each time a key is used, the key's "timer" is reset. Default is 1800 (half an hour). -
max-cache-ttl-ssh
= maximum length of time that any key will be held in memory, even if it has been used recently. Default is 7200 (two hours).
default-cache-ttl-ssh 0
max-cache-ttl-ssh 0
ℹ️ These settings only affect SSH secret keys read from the disk.
Secret keys stored in a YubiKey are never sent to the computer, so
gpg-agent
cannot hold them in memory.
Restart gpg-agent
If you made any changes to the gpg-agent.conf
file, you need to restart the gpg-agent
process.
$ gpg-connect-agent killagent /bye
OK closing connection
$ gpg-connect-agent /bye
gpg-connect-agent: no running gpg-agent - starting '/opt/homebrew/Cellar/gnupg/2.4.0/bin/gpg-agent'
gpg-connect-agent: waiting for the agent to come up ... (5s)
gpg-connect-agent: connection to the agent established