GnuPG
GnuPG (GNU Privacy Guard), also known as GPG, is a free implementation of the OpenPGP standard (RFC 4880). GPG supports both symmetric and public-key cryptography, and typically operates using both.
GPG can be used for digital signing, authentication, and encryption of data. It is often used to encrypt and sign email messages, but can also be used with files or plaintext.
GPG supports hardware security devices with an OpenPGP module, such as the YubiKey.
app-crypt/gnupg includes gpg-agent which can be used as an ssh-agent.
Installation
USE flags
USE flags for app-crypt/gnupg The GNU Privacy Guard, a GPL OpenPGP implementation
+smartcard
|
Build scdaemon software. Enables usage of OpenPGP cards. For other type of smartcards, try app-crypt/gnupg-pkcs11-scd. Bring in dev-libs/libusb as a dependency; enable scdaemon. |
+tofu
|
Enable support for Trust on First use trust model; requires dev-db/sqlite. |
bzip2
|
Enable bzip2 compression support |
doc
|
Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally |
ldap
|
Add LDAP support (Lightweight Directory Access Protocol) |
nls
|
Add Native Language Support (using gettext - GNU locale utilities) |
readline
|
Enable support for libreadline, a GNU line-editing library that almost everyone wants |
selinux
|
!!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur |
ssl
|
Add support for SSL/TLS connections (Secure Socket Layer / Transport Layer Security) |
test
|
Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently) |
tools
|
Install extra tools (including gpgsplit and gpg-zip). |
tpm
|
Enable TPM support via app-crypt/tpm2-tss and build tpm2d. |
usb
|
Build direct CCID access for scdaemon; requires dev-libs/libusb. |
user-socket
|
try a socket directory which is not removed by init manager at session end |
verify-sig
|
Verify upstream signatures on distfiles |
wks-server
|
Install the wks-server |
Emerge
root #
emerge --ask app-crypt/gnupg
Additional software
GnuPG can be used alone, but integrates with a wide variety of software.
Mail clients
- PinePGP (mail-client/pinepgp).
- Mutt (mail-client/mutt) - a small but very powerful text-based mail client.
- Claws Mail - a powerful mail program which supports threading, GPG with GPGME, and automation.
- Evolution (mail-client/evolution) - a GNOME Microsoft Outlook work alike.
- KMail (kde-apps/kmail) - KDE's mail client.
- Installing KGPG (kde-apps/kgpg) might be of interest when using the KDE desktop environment. This small program allows for the generation of key pairs, importing keys from ASCII files, signing imported keys, exporting keys, among a few other nifty features.
Other
- Tor (net-vpn/tor) - can be used to contact keyservers anonymously.
Configuration
GPG requires very little or no configuration to actually be used, most configuration tends to be centered around how the gpg-agent and pinentry behave. It is entirely optional, but recommended to adjust the gpg configuration at ~/.gnupg/gpg.conf to increase security.
GPG Security
The following options are part of GLEP 63, some are already defaults:
- utf8-strings - by default, GPG assumes arguments are encoded in the same character set as
display-charset
, setting this option makes GPG interpret arguments atutf8
. - fixed-list-mode - default since GnuPG2.0.10 - Do not merge the user ID and primary key when using
--with-colon
output mode. - keyid-format - shows the key ID in the specified format, options with 0x in front add that to the key ID to notate that it is hexadecimal.
- personal-digest-preferences - Adjusts digest algorithm selection order, can be utilized to prefer stronger hash types when signing messages.
- default-preference-list - Sets the preference list, used by
setpref
in the edit menu, can be utilized to prefer stronger methods. - verify-options - show-uid-validity is enabled by default, this option is used to adjust which types of validation are shown when keys are verified.
- list-option - show-uid-validity is enabled by default, used to adjust which types of validation are shown when keys or signatures are listed.
- cert-digest-algo - The digest algorithm that will be used when signing a key.
- s2k-cipher-algo - The cipher algorithm which will be used by default for symmetric encryption.
- s2k-digest-algo - The digest algorithm which will be used to mangle passphrases used for symmetric encryption.
~/.gnupg/gpg.conf
Reference GLEP63 configuration# Assume that command line arguments are given as UTF8 strings.
utf8-strings
# when outputting certificates, view user IDs distinctly from keys:
fixed-list-mode
# long keyids are more collision-resistant than short keyids (it's trivial to make a key
# with any desired short keyid)
# NOTE: this breaks kmail gnupg support!
keyid-format 0xlong
# when multiple digests are supported by all recipients, choose the strongest one:
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
# preferences chosen for new keys should prioritize stronger algorithms:
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 BZIP2 ZLIB ZIP Uncompressed
# You should always know at a glance which User IDs GPG thinks are legitimately bound to
# the keys in the keyring:
verify-options show-uid-validity
list-options show-uid-validity
# include an unambiguous indicator of which key made a signature:
# (see http://thread.gmane.org/gmane.mail.notmuch.general/3721/focus=7234)
# (and http://www.ietf.org/mail-archive/web/openpgp/current/msg00405.html)
sig-notation issuer-fpr@notations.openpgp.fifthhorseman.net=%g
# when making an OpenPGP certification, use a stronger digest than the default SHA1:
cert-digest-algo SHA512
s2k-cipher-algo AES256
s2k-digest-algo SHA512
Pinentry
app-crypt/pinentry is a helper application that gpg-agent uses to request the passphrase in a graphical window. It comes in many flavors, including: gtk3, qt5, tty, and curses.
Building pinentry-curses is recommended, as it is typically used as a fallback pinentry.
If app-crypt/pinentry was installed with more than frontend, it is possible to choose between them with the eselect pinentry command:
root #
eselect pinentry list
Available pinentry binary implementations: [1] pinentry-gnome3 [2] pinentry-qt5 * [3] pinentry-curses [4] pinentry-tty
root #
eselect pinentry set pinentry-qt5
eselect pinentry changes the symlink of /usr/bin/pinentry to the selected pinentry helper.
If GPG gives an error like:
user $
gpg -o /dev/null -s /etc/hostname
gpg: signing failed: pinentry error gpg: signing failed: pinentry error
user $
dbus-launch gpg -o /dev/null -s /etc/hostname
pinentry-qt & KWallet
pinentry-qt is capable of storing passwords in KDE's KWallet (or in any Secret Service compatible keyring.)
Ensure kde-frameworks/kwallet is installed, then in System Settings (provided by kde-plasma/systemsettings), under KDE Wallet, make sure the following are checked:
- Enable the KDE wallet subsystem
- Use KWallet for the Secret Service interface
Next, configure pinentry-qt to use Secret Service by creating this file:
/etc/profile.d/pinentry.sh
Make pinentry-qt use KWalletexport PINENTRY_KDE_USE_WALLET=1
Finally, logout & restart to make sure any lingering gpg-agent processes get the new configuration.
The instructions above don't seem to be working with any release of KWallet. The next section provides an alternative method for storing GPG passphrases in KWallet.
pinentry-kwallet & KWallet
pinentry-kwallet is also capable of storing passwords in KDE's KWallet.
Ensure kde-frameworks/kwallet is installed, then in System Settings (provided by kde-plasma/systemsettings), under KDE Wallet, make sure the following are checked:
- Enable the KDE wallet subsystem
- Use KWallet for the Secret Service interface
The GURU repo must be enabled in order to install kde-apps/kwalletcli. Follow the steps at this wiki page to enable and sync the GURU repository.
kde-apps/kwalletcli can then be installed:
root #
emereg --ask --verbose kde-apps/kwalletcli
To instruct gpg-agent to use pinentry-kwallet, create the following file:
~/.gnupg/gpg-agent.conf
Attach pinentry-kwallet to gpg-agentpinentry-program /usr/bin/pinentry-kwallet
Finally, logout & restart to make sure any lingering gpg-agent processes get the new configuration.
~/.gnupg/gpg-agent.conf overrides any settings applied with eselect pinentry set. Its contents must be commented out if pinentry selection is to be managed by eselect pinentry again.
kde-apps/kwalletcli is not an official KDE package. It is part of the MirBSD project. Make sure to carefully assess whether it would be a wise decision to trust them with such an important aspect of system security.
Key management
Generating keys
Gentoo Developers should follow Gentoo Infrastructure's key generation instructions.
gpg --full-generate-key can be used to generate a basic keypair, but using gpg --expert --full-generate-key offers many useful options, such as separate sign/certify certificates.
The first time the gpg command is executed, the directory ~/.gnupg will be created along with ~/.gnupg/pubring.kbx
Primary key
The GPG key creation process can be started with:
user $
gpg --expert --full-generate-key
gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(9) ECC and ECC
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(13) Existing key
(14) Existing key from card
Your selection? 11
(11) ECC (set your own capabilities) is selected, so this first generated key will only have the certify function. Additional subkeys may be created for encryption, sign, and/or authentication capabilities.
By default, the first key should have the sign and certify options set, remove the sign option with s:
Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
Current allowed actions: Sign Certify
(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? s
Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
Current allowed actions: Certify
(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? q
After selecting q, (1) Curve 25519, or whatever key type is preferred can be selected.
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
Once the primary key type is selected, there's an option to set the expiration date for the primary key. It is important to understand that the meaning of setting the expiration date for the primary key is different from the meaning of setting it for a subkey. In the case of a subkey, setting an expiration date can help with security because if its private key is leaked, the public key will eventually expire, minimizing the possible attack period. But this assumes that the subkey was kept separate from the primary key and the primary key was not compromised. However, as time passes and new attack vectors emerge, old unrevoked expired keys will be renewed and used by attackers. In the case of a primary key, the expiration date does not help with security because if the private key is leaked and its password is compromised, an attacker can renew the expired public key. The GNU Privacy Handbook recommends setting a primary key expiration date only in case the key and revocation certificate are lost (but not compromised). [1] Therefore, expiration cannot be a substitute for key revocation. An expiration date 3-1 years in the future is reasonable for moderate-high security.
If keys are lost or potentially compromised, the revocation certificate must be shared as expired keys can be renewed.
Setting the expiry to 0 makes the key never expire. [2]
It is possible to make the key expire on a specific date. This method should be preferred because it allows to keep an eye on expiration renewals. This method also allows to set a single expiration date for all subkeys, even those that will be created in the future.
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) 2026-01-01
Now that the key parameters have been defined, identification information must be provided.
It is possible to use names shorter than 5 characters with GPG by using
--allowfreeform-uid
, but this may cause issues when matching recipient names, requiring the fingerprint to be used instead of the key owner name.Finally, a passphrase must be added to the key. This passphrase is important, because it is used to protect the private key.
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/D2A5C10E2F7BAC36DDBC0AFCF980BCF1FADC7479.rev'
public and secret key created and signed.
pub ed25519 2023-04-25 [SC]
D2A5C10E2F7BAC36DDBC0AFCF980BCF1FADC7479
uid Larry (wiki example key) <larry@gentoo.org>
Take note of where the revocation certificate is located, this can be used to revoke keys in the event of unauthorized key/passphrase access.
At this point, only the primary [C]ertify (key signing key) key has been created, typically [S]igning and [E]ncryption keys are created.
Add a signing key
To view and edit the created key, gpg --expert --edit-key D2A5C10E2F7BAC36DDBC0AFCF980BCF1FADC7479 can be used. gpg --expert --edit-key Larry should also work, as long as Larry exists as a user in the detected keyrings.
user $
gpg --expert --edit-key D2A5C10E2F7BAC36DDBC0AFCF980BCF1FADC7479
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
(14) Existing key from card
Your selection? 10
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
Keys must be saved with the save command in gpg, quitting will not save generated keys.
Add an encryption key
user $
gpg --expert --edit-key D2A5C10E2F7BAC36DDBC0AFCF980BCF1FADC7479
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
(14) Existing key from card
Your selection? 12
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
Like with the creation of the sign and certify key, an expiration date must be set, and GPG will prompt for the key password before adding the key.
Keys must be saved with the save command in gpg, quitting will not save generated keys.
Add an authentication key
An Authentication key must be created to use GPG keys for SSH.
The authentication key can be created with:
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
(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? s
Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions:
(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: Authenticate
(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished
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) 2026-01-01
Is this correct? (y/N) y
Really create? (y/N) y
Keys must be saved with the save command in gpg, quitting will not save generated keys.
Removing the secret primary key for safety
In this section, it is assumed that the primary key will only be used for certification and the rest of the operations (signing, authentication) are assumed to be performed using subkeys. Only in this case is it justified to extract the secret primary key and store it separately on another device (e.g. a flash drive). The primary key will only be required to create\renew keys or sign the keys of others. If the device is compromised in the future, only the subkeys will be compromised. This means that all keys that have been certified with the primary key will still be valid, and the damage will be limited to the scope of the subkeys, which will probably expire before the attacker can determine the password (best case scenario).
Extract the secret primary key (should be stored on another device):
user $
gpg --output secret.gpg --armor --export-secret-key D2A5C10E2F7BAC36DDBC0AFCF980BCF1FADC7479
Extract the secret subkeys:
user $
gpg --output subkeys.gpg --armor --export-secret-subkeys D2A5C10E2F7BAC36DDBC0AFCF980BCF1FADC7479
Remove all secret keys:
user $
gpg --delete-secret-keys D2A5C10E2F7BAC36DDBC0AFCF980BCF1FADC7479
Import the extracted secret subkeys:
user $
gpg --import subkeys.gpg
Ensure that only secret subkeys are present:
user $
gpg --list-secret-keys
In the above output the secret primary key must be labeled as sec#
.
Exporting keys
Listing keys
Loaded public keys can be displayed with gpg -k:
user $
gpg -k
Private keys can be listed by using gpg -K instead of gpg -k:
user $
gpg -K
Public keys
Public keys can be exported using --export
, to export keys in armored form to stdout:
user $
gpg --armor --export Larry
Or to a file:
user $
gpg --output larry.pub --export 1080E273CC9C0BF9B3A228EAA562DF903D0BB7F6
In this case, Larry or 1080E273CC9C0BF9B3A228EAA562DF903D0BB7F6 can be used as parameter for
--export
, since both the keygrip and user names are valid ways to reference keys in GPG.If
--armor
is omitted, binary data will be written to stdout. The --armor
adds a GPG header and footer to the data and encodes it using Base64, so it can be easily copied or even printed.Private Keys
Private keys can be exported with: gpg --output {key}.secret.gpg --export-secret-keys {key} and gpg --output {key}.secret-sub.gpg --export-secret-subkeys {key} can be used, where {key} is the uid or fingerprint associated with the key.
Importing keys
A key can be imported from a file using: gpg --import keyfile.asc, or from stdin using gpg --import where the key can be pasted, and loaded by sending an EOF using Ctrl+D.
Gentoo release keys
Gentoo's GPG keys can be imported by running:
user $
wget -O - https://qa-reports.gentoo.org/output/service-keys.gpg | gpg --import
or
user $
gpg --import /usr/share/openpgp-keys/gentoo-release.asc
Loading a key from stdin
user $
gpg --import
If a private key is being loaded, pinentry may prompt for the key passwords:
user $
gpg --import larry.secret*
Be careful when verifying keys. This is one of the weak points of public key cryptography.
When importing key backups, it may make sense to mark the keys as ultimately trusted:
user $
gpg --edit-key Larry
Signing keys
An imported key can be signed (certified) once it's verified.
Certifying a key implies it is trusted by the signer. The signed key can be sent back to the owner, and and the key could be redistributed, so anyone who trusts the key that was used to sign that key can implicitly trust the signed key.
Here, the repomirror key is being signed by Larry:
user $
gpg --edit-key repomirrorci@gentoo.org
If Larry sent this signed key to someone, and someone else sent it to someone who knew and trusted Larry, they would have reason to trust the key, even if it was distributed using an insecure method.
When a key is marked as not trusted, signatures can also be used to designate that a certain user does not trust the key.
Exchanging keys with key servers
Configuring a default key server
To make gpg use keys.openpgp.org as the default key server, the following configuration can be used:
~/.gnupg/gpg.conf
Make GPG use keys.openpgp.org as the default keyserverkeyserver keys.openpgp.org
This configuration is equivalent to adding
--keyserver keys.openpgp.org
to every relevant gpg command.Sending keys to key servers
Gentoo Developers should follow Gentoo infrastructure's key sending instructions.
Once keys are generated, they can be shared with a keyserver. This makes it easier for others to import the key.
To send the keys to the openpgp keyserver:
user $
gpg --keyserver keys.openpgp.org --send-key D2A5C10E2F7BAC36DDBC0AFCF980BCF1FADC7479
gpg: sending key 0xF980BCF1FADC7479 to hkp://keys.openpgp.org
Other keys which have been certified may also be sent to a keyserver, this is announces that one key holder trusts (or distrusts) another key.
Getting keys from key servers
To obtain Larry's uploaded keys, the --search-keys
parameter can be used with identifying information such as the email address:
user $
gpg --keyserver keys.openpgp.org --search-keys larry@gentoo.org
When importing keys from a keyserver, be sure to check the key, as multiple keys may match a search.
Refreshing existing keys
Existing PGP keys should be refreshed on a regular interval (twice a month is common). To refresh keys, define a key server with which to connect:
user $
gpg --keyserver hkps://keys.gentoo.org --refresh-keys
This command can be added to a cron job or systemd timer.
GPG Agent
app-crypt/gnupg is packaged with gpg-agent which can be used to cache passphrases and manage unlocked key access.
xfce-base/xfce4-meta will try to automatically run gpg-agent and ssh-agent. This can make identity management more confusing.
gpg-agent can be configured on a per-user basis with ~/.gnupg/gpg-agent.conf
Options are documented in man gpg-agent under OPTIONS, simply omit the leading dashes.
~/.gnupg/gpg-agent.conf
Configure gpg-agent to use /usr/bin/pinentry with a ttl of 30 minutespinentry-program /usr/bin/pinentry
no-grab
default-cache-ttl 1800
~/.gnupg/gpg-agent.conf
Configure gpg-agent with ssh-agent supportenable-ssh-support
GPG must be configured to use gpg-agent, this can be accomplished with:
~/.gnupg/gpg.conf
Configuring GnuPG to use a GPG agentuse-agent
If the
use-agent
option is not configured, GPG may not prompt for smartcard pinentry.Configuration changes can be reloaded with:
user $
gpg-connect-agent reloadagent /bye
Smart Card
To use GPG with a hardware key/security key/smart card, ensure that the smartcard
USE flag is enabled -- this will include the scdaemon service; scdaemon, or "smart card daemon", is used by gpg-agent.
/etc/portage/package.use/gnupg
app-crypt/gnupg smartcard
root #
emerge --ask -uND app-crypt/gnupg
To read smart cards, GPG uses the CCID driver, but there are two ways to implement the driver: built-in and stand-alone.
Installing the stand-alone CCID driver might prevent some applications from reading smart cards depending on certain USE flags.
For example, if app-crypt/gnupg (GPG) is installed with the smartcard
USE flag, it will include the scdaemon service. If the usb
USE flag is also enabled, scdaemon will have the additional functionality of being a smart card reader -- allowing GPG to read smart cards without any additional dependencies.
The issue is that if the stand-alone CCID driver, app-crypt/ccid, is installed, it will conflict with the built-in CCID driver for scdaemon -- preventing GPG from reading smart cards. But some packages (such as KeePassXC) require the stand-alone driver to use features provided by smart cards. There are two solutions to fix this, both of which make pcscd the smart card reader. After a solution has been chosen, see PCSC-Lite for additional configuration if needed.
- Solution 1:
Install GPG with the usb
USE flag disabled then terminate the gpg-agent process then restart pcscd.
/etc/portage/package.use/gnupg
app-crypt/gnupg -usb
root #
emerge --ask -uND app-crypt/gnupg
root #
killall gpg-agent
root #
rc-service pcscd restart
- Solution 2:
Tell scdaemon to not use its built-in CCID driver -- this has the same affect if scdaemon started with the --disable-ccid
option; see man scdaemon.
~/.gnupg/scdaemon.conf
disable-ccid
Also ensure to terminate the gpg-agent process then restart pcscd.
root #
killall gpg-agent
root #
rc-service pcscd restart
At this point, GPG should be able to read smart cards. To test this, plug in an OpenPGP-compatible smart card and run the following command:
user $
gpg --card-status
If the output looks similar to the output above, then GPG can read smart cards.
Using gpg-agent for SSH
To use gpg-agent's SSH socket for SSH, some environment variables need to be set. The commands in the following file boxes come from info gnupg and man gpg-agent, where it's stated that if ssh agent support is enabled, ssh needs to be told about it by adding the following commands.
GPG_TTY is an environment variable that should be set to ensure that the Curses-based Pinentry works correctly[3]. If this variable is not set, then gpg-agent might error out. For example, the following command will error out when GPG_TTY is not set[4]:
GPG_TTY variable can be set in ~/.bashrc file. This ensures that each terminal has a unique value that points to the path of itself.
~/.bashrc
export GPG_TTY="$(tty)"
Next, SSH_AGENT_PID variable must be unset because when ssh-agent starts, it stores the name of the agent's process ID (PID) in this variable. Since using gpg-agent instead of ssh-agent, there is no need of this environment variable. See man ssh-agent for more information.
~/.bashrc
unset SSH_AGENT_PID
Finally, SSH_AUTH_SOCK variable need to be set. When ssh is used to access a remote host, gpg-agent will be used instead of ssh-agent -- this allows use GPG keys to login instead of a simple password. ssh-agent uses the SSH_AUTH_SOCK environment variable to determine which socket to use; SSH_AUTH_SOCK must be changed to point to the socket created by gpg-agent.
The test involving the gnupg_SSH_AUTH_SOCK_by variable is for the case where the agent is started as gpg-agent --daemon /bin/sh, in which case the shell inherits the SSH_AUTH_SOCK variable from the parent[5][6].
~/.bashrc
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi
The following alias is needed because SSH will be using gpg-agent instead of ssh-agent. The problem is that gpg-agent only stores the tty of where it was first started; so if user try to ssh in another terminal, the Pinentry will pop up in the terminal that started gpg-agent, not the one that ran ssh. To fix this, update the current tty to gpg-agent before run ssh.
~/.bashrc
alias ssh="gpg-connect-agent updatestartuptty /bye >/dev/null && ssh"
At this point, modifying ~/.bashrc file is finished, but GPG need to be aware of which keys should be used for SSH authentication; this can be done by telling GPG the keygrip of the authentication keys.
Keygrips can be obtained by running:
user $
gpg --list-secret-keys --with-keygrip
Where the [A] key is the Authentication key, which is used for ssh login.
Prior v2.3.7
gpg-agent only uses auth keys for SSH whose keygrip is present in ~/.gnupg/sshcontrol.
To allow gpg-agent to use the specified GPG key for SSH auth:
~/.gnupg/sshcontrol
0CA0F1710A5837577FB10177355BE575A425D76D
From v2.3.7
gpg-agent deprecates use of ~/.gnupg/sshcontrol file instead recommends setting Use-for-ssh attribute in auth key files which should be used for SSH.
Setting Use-for-ssh attribute can be done in two ways. One with editor and other using gpg-connect-agent:
user $
echo "Use-for-ssh: true" >> ~/.gnupg/private-keys-v1.d/0CA0F1710A5837577FB10177355BE575A425D76D.key
user $
gpg-connect-agent 'KEYATTR 0CA0F1710A5837577FB10177355BE575A425D76D Use-for-ssh: true' /bye
It is possible to use different values than "true" which behave differently. For more details see the --enable-ssh-support section of gpg-agent(1) .
There was a bug which prevented use of above gpg-connect-agent command which has been fixed now.
Forwarding GPG Agent over SSH
This is potentially dangerous, forwarding the GPG agent socket should only be done in trusted environments.
The remote host must have the corresponding public keys. Keys can be transferred manually, or the remote keyring can be replaced with the local one using:
user $
scp ~/.gnupg/pubring.kbx remotehost:.gnupg/pubring.kbx
First, the remote server's SSH daemon must be configured to allow remote forwards to override local files with:
/etc/ssh/sshd_config
StreamLocalBindUnlink yes
Then, the path for the GPG agent sockets must be obtained on both systems with:
user $
gpgconf --list-dirs
The local system's S.gpg-agent.extra socket will be forwarded to the remote system's S.gpg-agent socket.
SSH can be configured to automatically forward the GPG agent socket with:
~/.ssh/config
Automatically forward the GPG agent socket over SSHhost remoteHost
HostName 1.2.3.4
RemoteForward /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra
Changing pinentry for SSH logins
If gpg-agent is used over SSH, a graphical pinentry password prompt will not come up in the login shell. This causes all operations that require a password to fail. The following snippet can be added to ~/.bash_profile, this tells gpg-agent to use a curses prompt in the current shell. The snippet does not affect the pinentry settings when using local shells.
~/.bash_profile
Use curses pinentry for SSH loginsif [[ -n "$SSH_CONNECTION" ]] ;then
export PINENTRY_USER_DATA="USE_CURSES=1"
fi
Automatically starting the GPG agent
Generic
A generic method to autostart the GPG agent is to add gpgconf --launch gpg-agent
to a shell's rc file.
~/.bashrc
Autostart gpg-agent on shell initgpgconf --launch gpg-agent
KDE
KDE manages the GPG agent using the following files:
- /etc/xdg/plasma-workspace/env/10-agent-startup.sh - System agent startup configuration
- /etc/xdg/plasma-workspace/env/10-agent-shutdown.sh - System agent shutdown configuration
- ~/.config/plasma-workspace/env/gpg-agent.sh - User startup configuration
- ~/.config/plasma-workspace/shutdown/gpg-agent.sh - User shutdown configuration
The system configuration should contain a template for the GPG agent, it can be activated by uncommenting the following. To enable it for a single user, the configuration must be added to the user configuration.
/etc/xdg/plasma-workspace/env/10-agent-startup.sh
Make Plasma automatically start the GPG agentif [ -x /usr/bin/gpg-agent ]; then
if [ -x /usr/bin/gpgconf ]; then
gpgconf --launch gpg-agent >/dev/null 2>&1
if [ $? = 2 ]; then
eval "$(/usr/bin/gpg-agent --enable-ssh-support --daemon)"
fi
fi
fi
/etc/xdg/plasma-workspace/shutdown/10-agent-shutdown.sh
Make Plasma shut down the GPG agentif [ -n "${GPG_AGENT_INFO}" ]; then
kill $(echo ${GPG_AGENT_INFO} | cut -d':' -f 2) >/dev/null 2>&1
fi
Usage
Some parameters that apply to several GPG commands are:
- --armor - Adds PGP headers and footers to the data encoded as base64, useful when outputting to stdout
- --local-user or -u - Specifies the key to use for signing
- --output or -o - The output file, stdout is used otherwise
The order of the parameters is important, generally
--armor
should be used as the first argument.Signing
Signing verifies that someone with the private key associated with a known public key signed the data. If user trust that the key holder securely stores their key, then the user can be reasonably certain they sent a message signed with it. It can be used alongside encryption to ensure that a message can only be read by the intended recipients, and can be verified as coming from the correct source.
Data can be signed with --sign
or -s
:
user $
gpg --armor --sign --local-user larry
This alone does not encrypt the data.
Clear signing
Plaintext data can be signed, to verify the sender or publisher of the data. Unlike --sign
, --clear-sign
will keep the message in plaintext, putting the signature below it:
user $
gpg --clear-sign --local-user Larry
--clear-sign
implies the data should be armored.Detached signature
GPG can be used to sign data, keeping the signature separate from the data itself. The signature file can be distributed with the data. This is accomplished by using --detach-sig
. The following command will output a file named sign-me.sig which contains a signature for the file sign-me:
user $
gpg --armor --detach-sig --local-user Larry --output sign-me.sig sign-me
Symmetric Encryption
GPG's Symmetric encryption can be used to cipher data to be accessible by anyone who possesses the cipher key.
Available cipher algorithms can be viewed with gpg --version under Cipher::
user $
gpg --version
A cipher type can be selected with --cipher-algo
, and symmetric encryption can be used with --symmetric
or -c
:
user $
gpg --armor --symmetric --cipher-algo AES256
Signed
Anyone who decrypts symmetrically encrypted data will not be able to verify the authenticity of it without a signature or external (non-GPG) methods being used. To sign this symmetrically encrypted data, use:
user $
gpg --armor --local-user Larry --sign --symmetric --cipher-algo AES256
Asymmetric (Public Key) Encryption
GPG is generally used to perform asymmetric cryptography.
To send a message to a recipient, first view available public keys with gpg -k:
user $
gpg -k
To encrypt a message to Larry, use --encrypt
or -e
with Larry as the recipient:
user $
gpg --armor --recipient Larry --encrypt
Signed
This message can also be signed, so the recipient can verify the sender:
user $
gpg --armor --local-user Larry --sign --recipient Larry --encrypt
Signature verification
Verifying the signature of signed data is very important, if this is not done, the sender of the data is not validated. Verification is generally done using the --verify
flag:
user $
gpg --verify
Detached signature
Using the detached signing example, the file sign-me can be verified by running:
user $
gpg --verify sign-me.sig sign-me
Decryption
The method for decrypting asymmetric or symmetric data is the same in GPG, the --decrypt
or -d
flag is used:
Decrypting:
user $
gpg --decrypt
Decrypting and verifying signature:
user $
gpg --decrypt
user $
gpg -d
GnuPG interfaces
S/MIME is more commonly used/supported than GPG for emails, but there is no harm in using GPG (other than it not integrating with Microsoft services)
Seahorse
Seahorse (app-crypt/seahorse) aims to be a GnuPG GUI interface for the GNOME desktop. The software has been evolving fast, but it still lacks many important features that can be found in Kgpg or the command line version.
Troubleshooting
See also
- PCSC-Lite — implements the PC/SC international standard for PC to smartcard reader communication.
- YubiKey/GPG
External resources
- https://www.void.gr/kargig/blog/2013/12/02/creating-a-new-gpg-key-with-subkeys/ - An article explaining the creation of subkeys.
- https://keys.openpgp.org/ - OpenPGP.org's PGP infrastructure. Key server is running the Hagrid keyserver software. Use hkps://keys.openpgp.org for accessing from gpg.
- https://keys.gentoo.org/ - Gentoo Infrastructure's official PGP key server.
- https://www.gnupg.org/gph/en/manual.html - John Michael Ashley's "The GNU Privacy Handbook". Very good book for beginners.
References
- ↑ https://www.gnupg.org/gph/en/manual.html#AEN526
- ↑ https://www.rfc-editor.org/rfc/rfc4880#section-5.2.3.6
- ↑ https://www.gnupg.org/documentation/manuals/gnupg/Common-Problems.html
- ↑ https://dev.gnupg.org/T1434
- ↑ https://wiki.archlinux.org/title/GnuPG#Set_SSH_AUTH_SOCK
- ↑ https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=agent/gpg-agent.c;hb=7bca3be65e510eda40572327b87922834ebe07eb#l1307
This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Gustavo Felisberto, John P. Davis,
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.