Skip to content

This document is a WORK IN PROGRESS.
This is just a quick personal cheat sheet: treat its contents with caution!


GNU Privacy Guard (GnuPG/GPG)

  • Pretty Good Privacy (PGP)

    Pretty Good Privacy is proprietary software that provides cryptographic privacy and authentication for data communication. PGP is used for signing, encrypting, and decrypting texts, e-mails, files, directories, whole disk partitions and to increase the security of e-mail communications.

    It was originally written by Phil Zimmerman in 1991. After several changes of hands, it’s now owed by Symantec Corp. They also own the registered trademark for "PGP", "Pretty Good" and "Pretty Good Privacy".

  • OpenPGP

    After PGP took off in popularity, others wanted to write software that was compatible with the PGP format.

    In 1997, PGP Inc proposed to the IETF a standard called OpenPGP and allowed various uses of the name "OpenPGP". This was accepted and the IETF formed the OpenPGP Working Group.

    The OpenPGP protocol is currently formalized in the obsolete RFC 2440 and new RFC 4880.

  • GNU Privacy Guard (GnuPG/GPG)

    GNU Privacy Guard, also known as GnuPG and GPG, is the Free Software Foundation’s implementation of the OpenPGP protocol (written almost entirely by Werner Koch).

    Like PGP, it provides cryptographic privacy and authentication for data communication (signing, encrypting, decrypting, etc).

Reference(s)

Table of contents


Introduction

Keypair capabilities

GPG relies on the idea of asymmetric keypair: a private/secret key associated with a public key. They are called asymmetric, because they have different capabilities.

  • Private/secret key capabilities:

    • Decrypt something that have been encrypted with the associated public key only.
    • Sign something to prove other people its integrity (i.e what you signed has not been altered/tampered in any way) and to prove other people your identity (i.e. what you signed has been signed by you and no one else).
    • Certify a trusted public key, one of yours or someone else's. Certifying a public key is actually signing it, but certification is a specific signing mechanism only applied to public keys.
    • Authenticate to something, e.g. log into a machine via SSH. Authenticating is actually a signing challenge, but authentication is a specific signing mechanism only applied to that challenge.
  • Public key capabilities:

    • Encrypt things that can only be decrypted with the associated private/secret key.
    • Verify things that have been signed by the associated private/secret key only.

Note

When creating a keypair, you can choose to enable or disable some capabilities:

  • The Signing (S) capability (so the verify capability with it, because a public key has nothing to verify if its associated private/secret key cannot sign anything).
  • The Encryption (E) capability (so the decryption capability with it, because a private/secret key has nothing to decrypt if its associated public key cannot encrypt anything).
  • The Authentication (A) capability (independently from the signing capability).

Also note that a primary keypair always has the certification (C) capability, while sub keypairs cannot have that capability. This means that only the primary keypair can create sub keypairs and certify/revoke them.

More about primary and sub keypairs in a following section.

Example

Alice wants to share a secret message to Bob, in order to do so here are the steps follow:

  • Alice will have to sign the message with her private/secret key, this way she will prove to Bob that the message comes from her and no one else and she will also prove that the message has not been altered/tempered in any way (the message has kept its integrity).

  • Now Alice will have to encrypt the message with Bob's public key, this way she will prove to Bob that only him can read the content of the message.

  • At this point Alice can transmit the encrypted message to Bob by any means, even publicly.

  • After receiving it, Bob will decrypt the message with his private/secret key and verify Alice's signature with her public key. If no private/secret key has been compromised, then he can reasonably think that the message has been kept secret.

Public vs private/secret

It is clear, from the previous example, that public keys must be shared. You need to have the public key of the recipient in order to encrypt the file, and the recipient needs your public key to verify it. There is no danger in making your public keys just that—public. In fact, there are public key servers for that very purpose, as we shall see in the key servers section.

Warning

It’s very important to properly verify that a public key belongs to who you think it does. There is absolutely nothing to stop someone from creating a keypair using someone else’s email address and pretend it really belongs to that person. We will go into more details about this subject in the key verification section - for now, suffice to say that public keys have fingerprints which must be carefully verified, preferably in person.

Warning

Good key management is crucial in order to ensure not just the integrity of your keyrings but the integrity of other users' keyrings as well. The core of key management in GnuPG is the notion of signing keys. Key signing has two main purposes: it permits you to detect tampering on your keyring, and it allows you to certify that a key truly belongs to the person named by a user ID on the key. Key signatures are also used in a scheme known as "the web of trust" to extend certification to keys not directly signed by you but signed by others you trust. Responsible users who practice good key management can defeat key tampering as a practical attack on secure communication with GnuPG.

In contrast, the private/secret key must be kept... very private and very secret. If your public key can be online in the public domain, then your private/secret key must be kept secure (ideally offline, on a removable and write-protected media, in a very safe place). The whole security of GPG relies on making sure your private/secret key can’t be used by anyone else. In an Internet-connected world, this can be really tough. Moreover, your public key will build up its reputation over the year (after being signed by trusted people), so it can be really annoying to revoke your keypair. Ideally you would like to keep the same keypair for years, if not decades. How to keep your private key secure and hidden for so long (especially if you have to use it on a daily basis)?

GPG offers us a solution. It is possible to split off your "primary" key and keeping it really safe, then using "sub" keys for every-day use.

Primary keypair and sub keypairs

When you create a new GPG keypair then you will always create a primary keypair, you can also create/add an associated sub (subordinate) keypair, which is the case by default.

Tip

The primary and sub keypairs are bundled to facilitate key management and the bundle can often be considered simply as one keypair.

The problem is:

  • The primary key is too powerful, because it always has the certification (C) capability (while sub keypairs cannot have that capability, this means that only the primary keypair can create sub keypairs and certify or revoke). If someone steals your primary key, the certification capability allows to certify other people’s keys, and the primary key can even generate new sub keypair and revoke your sub keypair - totally stealing your identity!

  • In other words: your primary keypair is your identity! If the private/secret key is compromised, you will need to revoke it and create a new key (which can be really annoying, like said before, because your public key might build up a reputation over the year after being signed by trusted people).

The solution is:

  • Create a primary keypair with the least capabilities possible (so just the certification capability).

  • Create an associated sub keypair with the other capabilities needed.

  • Move the private/secret key of your primary keypair somewhere secure (ideally offline, on a removable and write-protected media, in a very safe place).

  • ... (TODO)

Because subordinate keypairs cannot have the certification (C) capability, if a sub keypair is compromised, then you can simply primary keypair can create sub keypairs and certify or revoke

Difference between revocation and deletion

TODO

One sub keypair per machine vs. one single sub keypair for all machines

One might be tempted to have one sub keypair per machine so that you only need to exchange the potentially compromised sub keypair of that machine. In case of a single sub keypair used on all machines, it needs to be exchanged on all machines in case of a compromising.

But, if you have multiple encryption sub keypairs, GPG is said to encrypt only for the most recent encryption sub keypair, and not for all known and not revoked encryption sub keypairs.

TODO:

  • Try to Sign with private/secret primary key (that has only C capability) and to Verify with public sub key (that has S capability): this should not be possible.

  • Try to Sign with private/secret primary key (that has SC capability) and to Verify with public sub key (that has S capability): this should be possible.

  • Try to Sign with private/secret primary key (that has SC capability) and to Verify with public sub key (that has no S capability): this shouldn't be possible.

  • Try to Encrypt with public primary key (that has only C capability) and to Decrypt with private/secret sub key (that has E capability): this should be possible.

  • Try to Encrypt with public primary key (that has only C capability) and to Decrypt with private/secret sub key (that has no E capability): this should not be possible.

  • Create multiple sub key pairs just with the E capability: is only the last private/secret keypair capable of decrypting something encrypted with the primary public key?

  • Create multiple sub key pairs just with the S capability: is only the last public keypair capable of verifying something signed with the primary private/secret key?


Avoid dotfile madness

Prior to installation, make sure you stay in control of your home directory.

Prerequisite(s)

See how to handle GnuPG related dotfiles.


Install

GnuPG should be installed by default, if not:

# emerge -a app-crypt/gnupg
# pacman -S gnupg

TODO


TODO


TODO



Config

TODO

WIP

If you need to set the default key more permanently then edit the file ~/.gnupg/gpg.conf and set the default-key parameter.

Tip

Note that Test User <tu@test.user> is the <USER-ID> of the key that we just created!


Use

Setup your keys

Primary keypair creation

Create a key, using the $ gpg --full-generate-key --expert command. The first time it is run, it will create some directories essential to the correct operation and implementation of GnuPG. You might have to run it again in order to create your keys:

$ gpg --full-generate-key --expert

    > gpg (GnuPG) 2.2.32; Copyright (C) 2021 Free Software Foundation, Inc.
    > 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? 8
    >
    > Possible actions for a RSA key: Sign Certify Encrypt Authenticate
    > Current allowed actions: Sign Certify Encrypt
    >
    > (S) Toggle the sign capability
    > (E) Toggle the encrypt capability
    > (A) Toggle the authenticate capability
    > (Q) Finished
    >
    > Your selection? S # (disable sign capability, which was toggle by default)
    >
    > Possible actions for a RSA key: Sign Certify Encrypt Authenticate
    > Current allowed actions: Sign Certify Encrypt
    >
    > (S) Toggle the sign capability
    > (E) Toggle the encrypt capability
    > (A) Toggle the authenticate capability
    > (Q) Finished
    >
    > Your selection? E (disable encrypt capability, which was toggle by default)
    >
    > Possible actions for a RSA key: Sign Certify Encrypt Authenticate
    > Current allowed actions: Sign Certify Encrypt
    >
    > (S) Toggle the sign capability
    > (E) Toggle the encrypt capability
    > (A) Toggle the authenticate capability
    > (Q) Finished
    >
    > Your selection? Q
    >
    > RSA keys may be between 1024 and 4096 bits long.
    > What keysize do you want? (3072) 4096
    > Requested keysize is 4096 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)
    > Key does not expire at all
    > Is this correct? (y/N) y
    >
    > GnuPG needs to construct a user ID to identify your key.
    >
    > Real name: Stéphane Tzvetkov
    > Email address: st@stephane.plus
    > Comment:
    > You are using the 'utf-8' character set.
    > You selected this USER-ID:
    >     "Test User <tu@test.user>"
    >
    > Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
    >
    > 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.
    >
    > gpg: key 4B6F2675F6D24EFA marked as ultimately trusted
    > gpg: revocation certificate stored as '/home/user/.config/gnupg/openpgp-revocs.d/4E54F7D32D247BB5A32AEE622A8F3875F6D42EFA.rev'
    > public and secret key created and signed.
    >
    > pub   rsa4096 1970-01-01 [C]
    >       8E54F7D38A427AA7A62AEE624B6F2675F6D24EFA
    > uid   Test User <tu@test.user>

Tip

Note that Test User <tu@test.user> is the <USER-ID> of the key that we just created!

Sub keypair creation

Your primary key is your online identity, and your identity and reputation are built up by having other people vouch for that key being yours by signing it themselves. So, since your primary key is very important and is built up over years, you want to protect it very much. In particular, you do not want to store it on a computer that might get stolen or hacked into; you want to keep your primary key off-line in a safe place.

This, of course, makes your primary key very inconvenient to use. So for day-to-day operations you want to use a key that is not such a big problem to replace if it gets compromised. This is why sub keypairs were invented.

A sub keypair is still a public/private keypair and is secure as long as only you have the private key. It is, cryptographically, just as secure as your primary key. The difference is that your reputation is only attached to it by your own signature, the signature from your private key. To use the Twitter analogy, the world trusts that you are your Twitter handle because all your followers say so (I know, it doesn't always really work that way, but analogies are hard!), and then with that trust established you can then much more easily convince the world you own your Instagram handle by just tweeting it and people will believe you because the tweet came from your account, which they trust.

You still want to keep your sub keypair safe, but now if it is compromised it is not the huge problem it would be if your primary key were compromised (or, in the analogy, someone hijacked your Twitter account). Now you can just revoke the sub keypair and issue a new one by signing a revocation certificate and a new sub keypair and posting them both on your public keyring (like tweeting "hey, my Instagram handle changed, don't use the old one, use this one instead"). This makes keeping your sub keypair on your laptop computer a more acceptable risk than keeping your primary key on it.

TL;DR Sub keypairs make key management much easier by separating the cryptographic functions of public keys from the trust and identity functions of (primary) public keys.

WIP

$ gpg --expert --edit-key "Test User <tu@test.user>"

    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? 8
       >
       > 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? A # add Authenticate capabilities, because sign and encrypt capabilities are already enabled by default
       >
       > Possible actions for a RSA key: Sign Encrypt Authenticate
       > Current allowed actions: Sign Encrypt Authenticate
       >
       >    (S) Toggle the sign capability
       >    (E) Toggle the encrypt capability
       >    (A) Toggle the authenticate capability
       >    (Q) Finished
       >
       > Your selection? Q
       >
       > RSA keys may be between 1024 and 4096 bits long.
       > What keysize do you want? (3072) 4096
       > Requested keysize is 4096 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)
       > Key does not expire at all
       > Is this correct? (y/N) y
       > Really create? (y/N) y
       > Enter passphrase: # Input the passphrase of the previous key
       >
       > 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  rsa4096/4B6F2675F6D24EFA
       >      created: 1970-01-01  expires: never       usage: C
       >      trust: ultimate      validity: ultimate
       > ssb  rsa4096/D663DA438B1DEFBC
       >      created: 1970-01-01  expires: never       usage: SEA
       > [ultimate] (1). User Test <tu@user.test>

    gpg> save # save and exit

Backup keypairs and remove the primary keypair

  • Export the private/secret primary key:

    $ gpg -a --export-secret-keys > master-secret-key.gpg
    

  • Export all the private/secret sub keys:

    $ gpg -a --export-secret-subkeys > sub-secret-keys.gpg
    

  • Save master-secret-key.gpg and sub-secret-keys.gpg on a physical device.

  • Delete the private/secret keys (you need to delete all the sub keypairs as well):

    $ gpg --delete-secret-key keyname
    

  • Enter the master password and confirm the deletion in the subsequent confirmation dialogs.

  • Restore the sub keypair:

    $ gpg --import sub-secret-keys.gpg
    

  • Check the result:

    $ gpg --list-secret-keys
      >
      > /Users/username/.gnupg/pubring.kbx
      > --------------------------------------------
      > sec#  rsa4096 2018-09-14 [C] [expires: 2020-09-13]
      >       5615F7C581E8450E34F9031703426E5D827D6A81
      > uid           [ultimate] User Name <username@mail.com>
      > ssb   rsa4096 2018-09-14 [S] [expires: 2018-09-16]
      > ssb   rsa4096 2018-09-14 [E] [expires: 2020-09-13]
      > ssb   rsa4096 2018-09-14 [A] [expires: 2020-09-13]
    

The # after the primary key means that the key is not stored locally.

Key verification

TODO

Key servers

See https://security.stackexchange.com/questions/186649/gpg-masterkey-and-subkey-for-encryption-and-signature-and-default-keys.

TODO

--refresh-keys
       Request updates from a keyserver for keys that already exist on the local  keyring.  This
       is useful for updating a key with the latest signatures, user IDs, etc. Calling this with
       no arguments will refresh the entire keyring.

--search-keys names
       Search the keyserver for the given names. Multiple names given here will  be  joined  to‐
       gether  to  create  the search string for the keyserver.  Note that keyservers search for
       names in a different and simpler way than gpg does.  The best choice is to use a mail ad‐
       dress.   Due to data privacy reasons keyservers may even not even allow searching by user
       id or mail address and thus may only return results when being used with  the  --recv-key
       command to search by key fingerprint or keyid.

--fetch-keys URIs
       Retrieve  keys  located at the specified URIs. Note that different installations of GnuPG
       may support different protocols (HTTP, FTP, LDAP, etc.).  When  using  HTTPS  the  system
       provided root certificates are used by this command.

GPG for SSH with gpg-agent

Reference(s)

Enable the gpg-agent SSH support:

$ echo "enable-ssh-support" >> $GNUPGHOME/gpg-agent.conf
$ gpg-connect-agent reloadagent /bye # tell the GPG agent to reload its configuration
    > OK

Set SSH_AUTH_SOCK so that SSH will use gpg-agent instead of ssh-agent. Add this to tour shell configuration file (i.e. $HOME/.bashrc or $HOME/.zshrc or whatever):

$ vi $HOME/.bashrc # or ${ZDOTDIR:-${HOME}}/.zshrc or wherever
    > ...
  + >
  + > # GPG - SSH setup
  + > unset SSH_AGENT_PID
  + > if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
  + >   export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
  + > fi
  + > export GPG_TTY=$(tty)
  + > gpg-connect-agent updatestartuptty /bye >/dev/null

$ source $HOME/.bashrc # or ${ZDOTDIR:-${HOME}}/.zshrc or wherever

Get the keygrip of the key you are interested in (e.g. Test User <tu@test.user>):

$ gpg --list-keys --with-keygrip
    > ...
    > pub   rsa4096 1970-01-01 [C]
    >       8E54F7D38A427AA7A62AEE624B6F2675F6D24EFA
    >       Keygrip = 7A523F57E28EABF523145F101E70A10582884EAA
    > uid           [ultimate] Test User <tu@test.user>
    > sub   rsa4096 1970-01-01 [SEA]
    >       Keygrip = 3A5C6B0B8E2ABE26D7030814B816BB6A093A92FC
    > ...

Now add the keygrip of your sub key to the list of approved keys:

$ touch $GNUPGHOME/sshcontrol
$ echo 3A5C6B0B8E2ABE26D7030814B816BB6A093A92FC >> $GNUPGHOME/sshcontrol

Check if the key is present in the SSH identities list:

$ ssh-add -l
    > 4096 SHA256:zZVNvVHtylqNVwK8JEpbQXCcKrStVdl6dVKIq7yszKw (none) (RSA)

Retrieve the public SSH key for the sub keypair:

$ gpg --export-ssh-key "Test User <tu@test.user>"

WIP

Reference(s)

GPG for Git

Reference(s)

Sign your Git commits with GPG

TODO

GPG for everyday use

WIP

  • TODO: check $ man gpg

  • List a summary of all local keys:

    $ gpg --list-keys
    
        > ...
        > pub   rsa4096 1970-01-01 [C]
        >       8E54F7D38A427AA7A62AEE624B6F2675F6D24EFA
        > uid   Test User <tu@test.user>
        > sub   rsa4096 1970-01-01 [SEA]
        > ...
    

  • List a summary of all local public keys:

    $ gpg --list-public-keys
    

  • List a summary of all local private/secret keys:

    $ gpg --list-secret-keys
    

  • Delete a secret key from your local public key list:

    $ gpg --pinentry-mode ask --delete-secret-key "Test User <tu@test.user>"
    

  • Delete a public key from your local public key list:

    $ gpg --delete-key "Test User <tu@test.user>"
    

  • Show your current default public key:

    $ gpg --armor --export
    
        > -----BEGIN PGP PUBLIC KEY BLOCK-----
        > ...
        > -----END PGP PUBLIC KEY BLOCK-----
    

  • Show the fingerprint for a key:

    $ gpg --fingerprint <USER-ID>
    

  • Search for keys containing a specific string:

    $ gpg --search-keys "tu@test.user"
    

  • Encrypt a File:

    $ gpg --encrypt --recipient 'user@emailaddress.com' example.txt
    

  • Decrypt a File

    $ gpg --output example.txt --decrypt example.txt.gpg
    

  • Export keys

    $ gpg --output ~/public_key.txt --armor --export <USER-ID>
    $ gpg --output ~/private_key.txt --armor --export-secret-key <USER-ID>
    

    Store these files to a safe location, such as a USB drive, then remove the private key file (e.g. using shred):

    $ shred -zu ~/private_key.txt
    

  • Import keys by retrieving the key files which you previously exported:

    $ gpg --import ~/public_key.txt
    $ gpg --allow-secret-key-import --import ~/private_key.txt
    

    Then delete the private key file (if any), e.g. using shred:

    $ shred -zu ~/private_key.txt
    

  • Revoke a key by creating a revocation certificate:

    $ gpg --output ~/revoke.asc --gen-revoke <USER-ID>
    

    After creating the certificate import it:

    $ gpg --import ~/revoke.asc
    

    Then ensure that key servers know about the revocation:

    $ gpg --send-keys <USER-ID>
    

  • Sign a file (by creating an associated signature file, i.e. the .asc file):

    $ gpg -ba filename
    

    OR, if you need to specify a particular key:

    $ gpg --default-key <USER-ID> -ba filename
    

    This then produces a file with a .asc extension which can be uploaded. If you need to set the default-key more permanently then edit the file ~/.gnupg/gpg.conf and set the default-key parameter.

  • Verify a signed file (with its associated signature file, i.e. the associated .asc file):

    $ gpg --verify filename.asc
    

  • Sign a public key (from/to a server):

    • Import the public key or retrieve it from a server:

      $ gpg --keyserver <keyserver> --recv-keys <USER-ID>
      

    • Check its fingerprint against any previously stated value:

      $ gpg --fingerprint <USER-ID>
      

    • Sign the key:

      $ gpg --sign-key <USER-ID>
      

    • Upload the signed key to a server:

      $ gpg --keyserver <keyserver> --send-key <USER-ID>
      

  • Change the email address associated with a GPG key

    gpg --edit-key <USER-ID>
    adduid
    

    Enter the new name and email address. You can then list the addresses with:

      list
    

    If you want to delete a previous email address first select it:

      uid <list number>
    

    Then delete it with:

      deluid
    

    To finish type:

      save
    

    Publish the key to a server:

      gpg --send-keys <USER-ID>
    

  • High-quality options for GPG for symmetric (secret key) encryption

    This is what knowledgable people consider a good set of options for symmetric encryption with GPG to give you a high-quality result.

    gpg \
      --symmetric \
      --cipher-algo aes256 \
      --digest-algo sha512 \
      --cert-digest-algo sha512 \
      --compress-algo none -z 0 \
      --s2k-mode 3 \
      --s2k-digest-algo sha512 \
      --s2k-count 65011712 \
      --force-mdc \
      --pinentry-mode loopback \
      --armor \
      --no-symkey-cache \
      --output somefile.gpg \
      filename # to encrypt
    
    gpg \
      --decrypt \
      --pinentry-mode loopback \
      --armor \
      --output somefile.gpg \
      filename # to decrypt
    

Troubleshooting

Inappropriate ioctl for device error

If you encounter the Inappropriate ioctl for device errors, like described here.

Then do the following:

$ vi ${XDG_CONFIG_HOME:-${HOME/.config}}/gnupg/gpg.conf # create it if not present
    > use-agent
    > pinentry-mode loopback

$ vi ${XDG_CONFIG_HOME:-${HOME/.config}}/gnupg/gpg-agent.conf # create it if not present
    > allow-loopback-pinentry

No pinentry error

If you encounter the No pinentry error, then follow the below steps.

  • Change the default pinentry-program to pinentry-tty (for a CLI-only experience):
    $ echo "pinentry-program /usr/bin/pinentry-tty" >> $GNUPGHOME/gpg-agent.conf
    $ gpg-connect-agent reloadagent /bye # tell the GPG agent to reload its configuration
        > OK
    

If you do not have /usr/bin/pinentry-tty, use /usr/bin/pinentry-curses instead (for older systems).

  • Then run again the gpg command causing the error, but with the --pinentry-mode ask option!

If this cheat sheet has been useful to you, then please consider leaving a star here.