Last year I explained how to use GnuPG for SSH authentication. Since then, GnuPG 2.1 “modern” was released, introducing some important changes. In particular, SSH authentication is now much easier, which prompted me to write this new note.
Enable SSH support in GnuPG Agent by adding the corresponding option
in the agent configuration file,
While GnuPG programs can start the GnuPG Agent on demand, starting
explicitly the agent is necessary to ensure that the agent is running
when a SSH client needs it. The two lines below, to be inserted into a
~/.xprofile script, are sufficient:1
gpg-connect-agent /bye export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
With the GPG agent running, you can start using it with your existing
SSH keys, exactly like you would use ssh-agent. For example, to
load your default
~/.ssh/id_rsa key into the agent, just
run as usual:
Let’s assume you already have an OpenPGP key such as the
following (note the
--expert flag, which will enable
advanced key generation options):
$ gpg2 --expert --edit-key alice Secret key is available. pub rsa4096/CB2F38F25B491A54 created: 2014-12-31 expires: 2017-12-30 usage: SC trust: ultimate validity: ultimate sub rsa2048/04BB7F8FDEC5E5D9 created: 2014-12-31 expires: 2015-12-31 usage: S sub rsa2048/BBB6B86627C2D43A created: 2014-12-31 expires: 2015-12-31 usage: E [ultimate] (1). Alice <email@example.com>
This is a 4096-bit master key with a 2048-bit subkey for encryption and a 2048-bit subkey for signing. We will add a new 2048-bit subkey for authentication purposes:
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?
Select (8) RSA (set your own capabilities):
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?
Select successively (S), (E), and (A) to remove the signing and encryption capabilities and enable the authentication capability.
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?
Once the only allowed action is Authenticate, select (Q) Finished to exit this sub-menu. The remaining of the procedure is like any other key generation:
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) 1y Key expires at Thu 31 Dec 2015 02:02:56 PM 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. pub rsa4096/CB2F38F25B491A54 created: 2014-12-31 expires: 2017-12-30 usage: SC trust: ultimate validity: ultimate sub rsa2048/04BB7F8FDEC5E5D9 created: 2014-12-31 expires: 2015-12-31 usage: S sub rsa2048/BBB6B86627C2D43A created: 2014-12-31 expires: 2015-12-31 usage: E sub rsa2048/7D2233B8833E70AF created: 2014-12-31 expires: 2015-12-31 usage: A [ultimate] (1). Alice <firstname.lastname@example.org> gpg> save
To tell the agent that the authentication subkey can be used with SSH, extract the keygrip of that subkey:
$ gpg2 --with-keygrip -k alice pub rsa4096/CB2F38F25B491A54 2014-12-31 [SC] [expires: 2017-12-30] Keygrip = D4DF0C35D3E22FA6AC37DA2E54FB03F73616A3CB uid [ultimate] Alice <email@example.com> sub rsa2048/04BB7F8FDEC5E5D9 2014-12-31 [S] [expires: 2015-12-31] Keygrip = 21B2EDF018D7CAF0B45644FDB753DD42307C4425 sub rsa2048/BBB6B86627C2D43A 2014-12-31 [E] [expires: 2015-12-31] Keygrip = 2E149DA9C5E46E0DECC6A17EFD8B5FB1DF1E1BAB sub rsa2048/7D2233B8833E70AF 2014-12-31 [A] [expires: 2015-12-31] Keygrip = ECF4591CC28EC303BB12D1E866C8B8AFFB675C7D
and write it into the
# List of allowed ssh keys. Only keys present in this file are used # in the SSH protocol. The ssh-add tool may add new entries to this […] ECF4591CC28EC303BB12D1E866C8B8AFFB675C7D
You may then verify that the key is indeed available for SSH by querying the agent for available identities:
$ ssh-add -l 2048 e3:40:d5:eb:ef:b1:3a:37:87:3d:a8:44:1d:81:ed:6a (none) (RSA)
Finally, extract the public key from the agent in a form suitable for
inclusion into a
$ ssh-add -L ssh-rsa AAAAB3NzaC1yc2EAA[…truncated output…]KhJHfdIcCMRF (none)
If you want to authenticate with an OpenPGP smartcard, you may refer to my previous note for GnuPG “stable” 2.0.x. The section about the OpenPGP smartcard is still valid for GnuPG “modern” 2.1.
--list-dirs agent-ssh-socketoption was added to gpgconf in GnuPG 2.1.14, to cope with the fact that, starting from GnuPG 2.1.13, the GnuPG Agent may store its sockets elsewhere than in GnuPG’s home directory.