Encrypt with GnuPG

Paul Guerin
8 min readJun 16, 2023

GnuPG is a powerful encryption tool.

To get started with installation of GnuPG, refer to this document:

The basic architecture

A user can create at least one user ID. You could also have multiple user IDs, where each user ID is for a particular purpose.

Each user ID will have a key pair. Each key pair is comprised of a public key (ie public master signing key, with one or more public subkeys) and a secret key (ie private master signing key, with one or more private subkeys).

Note: the private master signing key can also be known as a primary key.

Your key pairs are stored on a keyring for public keys, and another keyring for secret keys.

  • There is a keyring for all public keys in your possession.
  • And another keyring for your secret key, or multiple secret keys if you own more than one user ID.

Any public keys that you receive from others will be stored on the keyring for public keys too.

Note: In older versions of GnuPG, the public keyring was stored in a file named pubring.gpg, and the secret keyring stored in another file named secring.gpg.

Note: In more recent versions of GnuPG, all your keyrings are stored in a keybox format, which is a single file named pubring.kbx.

Also each public key can have multiple subkeys which can be expired either by date, or via a manual method.

Note: If you choose to share your public key with others, then it is only the public subkey that is actually shared.

Setup the following environment variables, and you are ready to go.

# For the Bash shell, set the prerequisite environment variable
export GPG_TTY=$(tty)

# For the Fish shell, set the prerequisite environment variable
set GPG_TTY $(tty)

Create a user ID and a key pair

Now the first step is to create a user ID and a key pair, and so then you’ll be able to use a public key cipher, and sign documents.

To accept the basic GnuPG defaults, you can use the following command:

# After a fresh install of GnuPG, create the basic GnuPG files
# in preparation to generate or import keys.
# ie .gnupg directory containing pubring.kbx and trustdb.gpg
gpg2 -k

# GnuPG version 2
gpg2 --gen-key

# or just gpg, if you know that it's an alias for gpg2
gpg --gen-key

You’ll be asked for a “real name” and “email address”, as this information will be used to create a user ID.

Note — there is no obligation to use a real name and real email address, especially if you are not intending to share your public key with anyone else.

Just as an example, I will use the following for a name and address:

  • example
  • example@mail.com

You can also refer to the user ID by the short name only, which in our example is just ‘example’.

GnuPG will also ask you for a secure passphrase for the secret key, and it should be at least 8 characters long, and contain at least 1 digit or special character.

Now to list the public key pair that I just created (and the corresponding subkey), you just need to specify the user ID of the key:

# list the public keys for this user
gpg --list-keys example

# list all the public keys
gpg --list-keys

Also you can get a breakdown of the public and secret key pairs can be obtained with:

# List all the public keys
gpg --list-public-keys

# List all the secret keys
gpg --list-secret-keys

So you can see as well as a public key (ie pub) plus public subkey (ie sub) you’ll also have a secret key (ie sec), plus a secret subkey (ie ssb), on your keyring.

Also a short-hand way to list the public and secret keys is as follows:

# List all the public keys
gpg -k

# List all the secret keys
gpg -K

At any time in the future, you can create additional public and secret subkeys on the same keyring.

This may be advantageous if you suspect your existing key has been hacked, and so you want to be able to create a new secret key to protect new documents.

Export and import

You can also export and import your keys for backup purposes.

# export the keys to a file in binary format
gpg --export-secret-keys --export-options backup --output ~/backup.key

# After a fresh install of GnuPG, create the basic GnuPG files
# in preparation to generate or import keys.
# ie .gnupg directory containing pubring.kbx and trustdb.gpg
gpg -k

# import the keys
gpg --verbose --import ~/backup.key

If you have public keys from other people, than you can also export and import the owner trust information.

# export the owner trust information
gpg --export-ownertrust > otrust.txt

# import the owner trust information
gpg --import-ownertrust < otrust.txt

If you have imported keys without the owner-trust information, then you’ll need to sign the public key with your secret key. To do this you need to specify your user ID:

# edit your keys
# gpg --edit-key <persons_name>
gpg --edit-key example

Then sign it, and save the results:

sign

check

save

Note — if you create another key pair, then the 1st secret key can be used to self-sign the 2nd public key.

Basic encryption and decryption use case

Now you are ready to encrypt your first document. For a recipient user named ‘example’ (ie myself), the following command takes the file named t.txt, and creates an encrypted file named t.txt.gpg.

Encryption using a public-key cipher

# Note1: encrypt a file for the recipient user named 'example'
# Note2: target must be a file and not a directory
# Note3: use --interactive to check if the encrypted file already exists
# Note4: use --sign to add a signature into the contents of the encrypted file

# ie allow decryption via the secret key
gpg --encrypt --interactive -r example t.txt

gpg --encrypt --interactive --sign -r example t.txt

# ie allow decryption via the secret key or passphrase
gpg --encrypt --symmetric --interactive -r example t.txt

gpg --encrypt --symmetric --interactive --sign -r example t.txt

Encryption using a symmetric cipher

# ie allow decryption via a passphrase
gpg --symmetric --interactive t.txt

gpg --symmetric --interactive --sign t.txt

# allow decryption via a passphrase or the secret key
gpg --symmetric --encrypt --interactive t.txt

gpg --symmetric --encrypt --interactive --sign t.txt

Note: if you get the error ‘No public key’, then you either (1) need to self-sign your public key, or (2) need to unexpire your public key.

Note: to encrypt a file for another recipient, you must first receive their public key before GnuPG will allow you to encrypt it.

Decryption

Decryption is also straight forward, but there is a check to make sure that I’m the intended recipient of the encrypted file.

If you just want to read the text, without decrypting to the file system, then just pipe to your favourite editor/pager.

Note: if you get a blank screen without a prompt, then simply pretend you have a prompt and type in your passphrase, then enter. Then you should see the decrypted output as expected.

# Pipe the decrypted output to the Less pager
gpg --decrypt t.txt.gpg| less

# Pipe the decrypted output to the Vim editor (readonly mode)
# R = read-only
# n = no swap file, use memory only
gpg --decrypt t.txt.gpg| vim -R -n -

# another pipe
vim -R -n <(gpg --decrypt t.txt.gpg)

Another option is to decrypt to standard output:

# Output to standard output with the '--output -' argument
gpg --output - --decrypt t.txt.gpg

To decrypt to a file, you can specify the new name of the file as follows:

# Output to a file named t.txt1
gpg --output t.txt1 --decrypt t.txt.gpg

You’ll be asked for your passphrase to unlock your secret key, and then the decrypted file will be generated.

Key maintenance

The official documentation says this about expired keys:

Once the subkey expires, those who wish to correspond with you must find your updated public key since they will no longer be able to encrypt using your expired key.

It is possible to create a key pair that does not expire. However it’s considered best practice to set expiry dates for each subkey.

For the GnuPG release 2.3.4, the default expiry date for a created key pair is 2 years into the future.

There are 3 ways to manage the subkeys :

  • Set expiry dates for every subkey, but extend the keys ahead in time so that they do not expire.
  • Allow the existing subkeys to expire, but unexpire them when you need to use them again.
  • Allow the existing subkeys to expire, and create new subkeys to replace the expired ones.

You may also manually revoke keys from the keyring, if you wish that existing encrpted documents in your possession can’t be decrypted anymore.

To perform key maintenance, enter the key maintenance session as follows:

# edit your keys
# gpg --edit-key <persons_name>
gpg --edit-key example

Extend the expiry date of a key pair

If your current secret key has expired, then you won’t be able to encrypt new files, and you won’t be able to sign new files either. (But you will still be able to create unsigned symmetric sipher files.)

Also note that any secret keys that have expired can still be used to decrypt existing documents that were encrypted with those keys. Expired secret keys can remain expired for as long as it’s convenient to leave them expired.

From the key maintenance session, to extend the expiry date of the public and secret keys, then save the status:

expire

save

Extend the expiry date of a pair of subkeys

From the key maintenance session, to extend the expiry date of the public and secret subkeys, then save the status:

key 1

expire

save

Add a pair of subkeys

From the key maintenance session, add another public and secret subkeys.

addkey

save

Enable or disable a pair of subkeys

The official documentation says this about the situation where someone else has stolen your keyring of secret keys (and your keys were not protected by a symmetric sipher):

Just as you can, an attacker can still read all documents encrypted to an expired subkey.

Enter the key maintenance session, as before.

Disable a pair of subkeys by selecting the subkeys, then disable, then save.

key 1

disable

save

Continue with your GnuPG journey with encrypted Tarballs:

--

--