OpenSSH Login with GnuPG (OpenPGP) Keys
OpenSSH Login with GnuPG Keys
Many people don’t know that they can use OpenPGP (GnuPG) keys to log in to the OpenSSH server. Instead, they generate two sets of keys and use them independently. Using OpenPGP keys to log in to the OpenSSH server can make our lives more convenient and more secure. Let’s start our journey.
What You Need
GnuPG 2.1.9
or later
Password Generator
Using secure passwords is one of the best security practices. It is recommended to use apg
or pwgen
as a password generator:
1 | $ dpkg -l | grep -E 'apg|pwgen' |
Usage:
1 | $ apg -a 1 -M SNCL -m 8 -x 8 -n 8 |
1 | $ pwgen -1 -s -B -y -n -c 8 8 |
Generate Key
Note that variable PP
is the sample password, and KF
is the generated master key fingerprint. Please replace them with your own corresponding password and master key fingerprint respectively.
1 | PP='Vx@e0l6y' |
1 | KF='EE84D73B6CEC596BDEB56EEF2F9DE5D06993DEF0' |
List Key
Let’s view the OpenPGP Keys we just generated:
1 | $ gpg -K ${KF} --with-keygrip |
Note that the purpose of the subkey DCA34AA211A525C3
contains the letter A
(auth
), indicating that it can be used for authentication, such as logging into an OpenSSH server.
Export SSH Key
Let’s export the public key that the OpenSSH server needs:
1 | $ gpg --export-ssh-key "${KF}" |
Note that the comment part 11A525C3
of this public key is the last 8 hexadecimal characters of the subkey DCA34AA211A525C3
.
Update ~/.ssh/authorized_keys in OpenSSH Server
The method of uploading the public key to the OpenSSH server depends on the configuration and deployment of the server. For common OpenSSH servers, it is usually directly added to the file ~/.ssh/authorized_keys
in the user directory:
1 | echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMpjycTr1bb3jNBU/AdtsKjDX1Kz79pZsvz4kHnGM5wg openpgp:0x11A525C3' >> ~/.ssh/authorized_keys |
Update ~/.gnupg/sshcontrol
In order to let the local gpg-agent
know that this OpenPGP subkey can be used for OpenSSH authentication, we need to add its keygrip
to the file ~/.gnupg/sshcontrol
.
Execute the following command to find the keygrip
of this subkey:
1 | gpg -K --with-keygrip ${KF} |
We can see that the Keygrip
of subkey DCA34AA211A525C3
is 8C1FC82074A83ED40D851259694BBFB92B94A344
, let’s add it to the file ~/.gnupg/sshcontrol
:
1 | $ echo '8C1FC82074A83ED40D851259694BBFB92B94A344' >> ~/.gnupg/sshcontrol |
Update ~/.gnupg/gpg-agent.conf
This step is optional and updates the file ~/.gnupg/gpg-agent.conf
to change the TTL
of the key and to display the fingerprint of the SSH key using SHA256
instead of MD5
:
1 | default-cache-ttl 1800 |
Update ~/.ssh/config
This step is also optional, because when gpg-agent
is not started, OpenSSH cannot use public key authentication, so we use a feature of the OpenSSH client configuration to automatically execute the command gpg-connect-agent
, which in turn uses a feature that automatically starts gpg-agent
when it finds that it is not started:
1 | $ vi ~/.ssh/config |
Note that although this step is optional, it executes UPDATESTARTUPTTY
, which ensures that gpg-agent
pops up the password input box in the current window and does not find the wrong window. This is particularly useful on Linux systems, especially when using terminal multiplexers such as tmux.
Update ~/.bashrc
For example, in the file ~/.bashrc
, ~/.bash_profile
or ~/.profile
, in the interactive login section, configure the environment variable GPG_TTY
:
1 | export GPG_TTY=`tty` |
If you do not want to log in again, you can execute the following command to make it take effect:
1 | $ source ~/.bashrc |
or:
1 | $ export GPG_TTY=`tty` |
Try OpenSSH Login
Now that everything is done, let’s try logging into OpenSSH using our GnuPG key:
1 | $ ssh <user>@example.com |
Enter the password we provided when generating the OpenPGP key, and we are logged in to the remote OpenSSH server.
Mapping of OpenPGP Keys and SSH Fingerprints
Sometimes we have many keys available for SSH login, and we may not be able to find the OpenPGP key corresponding to the SSH fingerprint. In this case, the following script is very useful:
1 |
|
Delete Key
Now that the test is complete, let’s delete the OpenPGP test key we just generated:
1 | $ gpg --delete-key --batch --yes ${KF} |
In addition, don’t forget to delete the records we added in the file ~/.gnupg/sshcontrol
and the file ~/.ssh/authorized_keys
. The changes to other files can be retained. Of course, if you want to delete GnuPG as well, you also need to delete the records we added in the file ~/.ssh/config
.
Wrapping Up
The pursuit of security, reliability and simplicity has always been one of our goals. Let’s start by using OpenPGP keys and GnuPG to log in to the OpenSSH server!
Reference
- https://www.gnupg.org/download/
- https://www.gnupg.org/documentation/manuals/gnupg/
- https://www.gnupg.org/documentation/manuals/gnupg/OpenPGP-Key-Management.html
- https://www.gnupg.org/documentation/manuals/gnupg/Operational-GPG-Commands.html
- TOFU not affected by Key deletion - https://dev.gnupg.org/T2859
- https://github.com/PowerShell/Win32-OpenSSH/releases/
- https://cheatsheets.chaospixel.com/gnupg/