Table of Contents
GnuPG is a compliant implementation of OpenPGP.
Installation
Gentoo
- snippet.bash
emerge -av gnupg
- snippet.bash
pacman -Syu gnupg
Concepts
As with SSH there are two parts to a key, the public and secret. Typically only your own secret keys will be stored on your system.
- snippet.bash
gpg --list-keys gpg --list-secret-keys
Key Generation
The following gives more options, if you opt for RSA the default number of bits (currently 3072 as of writing) is more than sufficient. If you want more security use elliptic curve Elliptic-curve cryptography options such as ed25519
- snippet.bash
gpg --full-gen-key
Subkeys
A master key is required for GnuPG but you can, and probably should, create subkeys to perform specific tasks. The reason being that these can, if compromised, be changed without changing your master.
Authentication
It is possible to save SSH keys as sub-keys within you GPG key as a sub-key that can then be used for authentication when required. For guidance I followed How to enable SSH access using a GPG key for authentication. It is possible to import your existing SSH keys into your GPG key
- snippet.bash
gpg --expert --edit-key my.email@address.com > 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 (14) Existing key from card Your selection? 11 Possible actions for a ECDSA/EdDSA key: Sign Authenticate Current allowed actions: Sign (S) Toggle the sign capability (A) Toggle the authenticate capability (Q) Finished Your selection? A Possible actions for a ECDSA/EdDSA key: Sign Authenticate Current allowed actions: Sign Authenticate (S) Toggle the sign capability (A) Toggle the authenticate capability (Q) Finished Your selection? S Your selection? Q Please select which elliptic curve you want: (1) Curve 25519 (3) NIST P-256 (4) NIST P-384 (5) NIST P-521 (6) Brainpool P-256 (7) Brainpool P-384 (8) Brainpool P-512 (9) secp256k1 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 Key does not expire at all 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. sec ed25519/700172212EF5818B created: 2020-11-20 expires: never usage: SC trust: ultimate validity: ultimate ssb cv25519/95437AC864ECE7F9 created: 2020-11-20 expires: never usage: E ssb ed25519/1B704D7D93B8DC1C created: 2020-12-02 expires: never usage: A [ultimate] (1). Some One <my.emaill@address.com>
You then need to enable SSH support in the GPG Agent, this is done through its configuration file which is located at ~/.gnupu/gpg-agent.conf
which should have the line…
- snippet.bash
enable-ssh-support
Ideally you should then also pre-specify the SSH keys to use by adding the keygrip (an indicator of the public and private components of the key) by adding it to ~/.gnupg/sshcontrol
file. First identify the keygrip for your SSH authentication sub-key…
- snippet.bash
gpg --list-secret-key --with-keygrp
Copy the Keygrip for the SSH key you just generated and add it to ~/.gnupg/sshcontrol
- snippet.bash
echo '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0987654321' >> ~/.gnupg/sshcontrol
Finally you need to tell the ssh-agent
to access the gpg-agent
by changing the value of SSH_AUTH_SOCK
. This depends on which shell you use, but add the following to ~/.bashrc
or ~/.zshrc
. It is this step that tells SSH to use the GPG subkey…
- snippet.bash
export SSH_AUTH_SOCK='$(gpgconf --list-dirs agent-ssh-socket)'
Since I use keychain to manage my SSH/GPG agent I already had the necessary lines to start the gpg-agent
, namely…
- snippet.bash
/usr/bin/keychain --agents ssh,gpg ~/.ssh/id_ed25519 my.email@address.com
Signing
Encryption
Copying
If you can SSH to another machine use scp
or rsync
to copy the files (thread). If not you need to encrypt your secret key with a one time password (see OpenKeyChain FAQ : What is the best way to transfer my own key to OpenKeychain.
- snippet.bash
gpg --armor --export-secret-keys your@email.com | gpg --armor --symmetric --output ~/.gnupg/ed25519.key.asc
TIP I use SolidExplorer on my Android devices which supports sFTP so I simply connected to my computer and copied the file over after having password protected it and the imported it to OpenKeyChain.
Android
On Andoird use OpenKeyChain to manage your keys, and they have an FAQ on What is the best way to transfer my own key to OpenKeychain? if you can not use sFTP (Solid Explorer supports sFTP though).
Configuration
gpg
Configuration of gpg
is done via ~/.gnupg/gpg.conf
.
gpg-agent
See Gentoo GnuPG : Using a GPG Agent
Configuration of gpg-agent
is done via ~/.gnupg/gpg-agent.conf
.
I also found on occassions that when I SSH'd in to a computer and then tried to SSH elsewhere the dialog box asking for my pin popped up but in the GUI on the host rather than under the TTY of the client, this was obviously annoying. I found a solution at Prefer Terminal for GnuPG Pinentry - Kevin Locke's Homepage, but I'm still not 100% convinced that using a GPG SSH sub-key managed by gpg-agent
is for me as it times out and I tire of having to enter my password (even though its sensible for it to do so), and prefer the persistence of ssh-agent
for managing SSH keys.
gpg-agent.conf
- snippet.bash
pinentry-program /usr/bin/pinentry no-grab # 0 prevents storage, max value is 7200 default-cache-ttl 1800 max-cache-ttl 1800 # Enable SSH authentication with sub-key (see also ~/.gnupg/sshcontrol) enable-ssh-support # Use TTY for password by default pinentry-program ${HOME}/.gnupg/pinentry-auto
gpg.confg
- snippet.bash
use-agent
Keychain / gpg-agent
Keychain can manage your gnupg and pass it on to the gpg-agent
. The following loads both SSH and GPG keys into their respective agents using Keychain, add it to your ~/.bashrc
/.zshrc
.
- snippet.bash
/usr/bin/keychain --agents ssh.gpg ~/.ssh/id_ed25519 your@email.com . ~/.keychain/$HOSTNAME-sh . ~/.keychain/$HOSTNAME-sh-gpg
Common Actions
Listing Keys
- snippet.bash
gpg --list-keys gpg --list-secret-keys
Exporting Keys
You will invariably want to share your public key, this is typically done as plain-text (the --armor
part).
- snippet.bash
gpg --list-keys gpg --export-keys --armor XXXXX > ./pub-gpg-key.asc
Sometimes you may need to move your key (e.g. transfer it to an Android device after its initial creation, although see What is the best way to transfer my own key to OpenKeychain?).
- snippet.bash
gpg --list-secret-keys gpg --armor --export-secret-keys XXXXX | gpg --armor --symmetric --output my-private-gpg-key.asc
Replacing Keys
This is fairly straight-forward, particularly if you've an alternative email address to use in which case you create a new key for that email address. I wanted to use an Elliptic Curve Cipher (ECC) as the fingerprint is smaller yet they are more secure. Run the following and select 9
for Elliptic Curve Ciphers, I opted for ED25519
so selected 1
then provided the required information.
- snippet.bash
gpg --expert --full-gen-key
Thats it you have a new key, you will want to export your new public key (see above), and possibly export it to a key server…
- snippet.bash
gpg --keyserver pool.sks-keyservers.net --send-key ASKLJLKAJS90890ASD gpg: sending key 700172212EF5818B to hkp://pool.sks-keyservers.net
If you use pass then you will want to re-encrypt the passwords using the new key which is simple, you just…
- snippet.bash
pass init your@email.com
…and it will go through the default ~/.password-store/
directory re-encrypting the passwords.
Deleting Keys
You can delete keys and secret keys…
- snippet.bash
gpg --delete-keys XXXXX gpg --delete-secret-keys XXXXX