GNU Privacy Guard

This is a guide for the GPG command line application that is available on Linux systems. It aims to provide all the necessary information for basic use of GPG. I am not an expert on GPG, PGP or encryption in general, so there is a possibility of incorrect information appearing here.

Why use GPG

While for most situations there are other applications which are more user friendly and sometimes better than GPG, it still makes sense to use it in case:

  1. Two people want to share data without the need for both of them to be online at the same time.
  2. Signing files, so that people know they come from you and have not been tampered with.

Even for these cases there are alternatives to GPG but it is up to you, if you trust them over the older and more widely adopted GPG.

How to use GPG

Pretty much all operations with gpg should be done under your user account (i.e. without sudo). If you can’t generate new key pair, check your permissions (see Viewing keys on disk).

Generate new key pair

GPG uses two keys to do its work. A public key that is shared with others so they can encrypt data before sending it to you and verify your signature. And a secret (also called private) key that only you have and you use it to decrypt the data and create file signatures.

gpg --full-gen-key
  1. Select the default RSA and RSA option. DSA/Elgamal is not better than RSA.
  2. Type in the key size. Pick the largest one, you should not notice a difference in performance.
  3. For signing it is fine to never expire. For encrypting you may want to have expiration date. Type in 0 for now and confirm.
  4. Type in a name associated with the keys. It will be visible to other people. It accepts spaces.
  5. Type in an email address. It will be visible to other people. It can be left empty.
  6. Type in a comment. It will be visible to other people. It can be left empty.
  7. If the resulting user ID is correct, continue with o.
  8. You are asked to provide a password. The password is not part of the keys, it is used to encrypt the secret key for safe storage on your computer. Don’t forget it of course or you won’t be able to use your secret key anymore.
  9. It will now generate the key pair. You should help it by moving mouse around, typing in another window etc.

Viewing keys

You can view your secret and public keys separately using the commands:

gpg --list-keys gpg --list-secret-keys

If you have a key exported to a file, you can view the key using:

gpg --import --import-options show-only keyfile.gpg

In the secret keys list, you will find the key you just created. It will look something like this:

sec rsa4096 2022-03-06 [SC] 0E87B99A648958A4079890BF03B12BFE717BDD61 uid [ultimate] Username (This is a comment.) <username@email.com> ssb rsa4096 2022-03-06 [E]

Your secret key is actually two keys. The first three letter word is the type of key, these are:
sec – secret (primary) key
ssb – secret subkey
pub – public (primary) key, there can be more than one
sub – public subkey, there can be more than one
uid – marks user ID associated with primary key, there can be more than one.

The two keys have different uses, marked with the letters in square brackets at the end:
S – signing
E – encrypting/decrypting
C – certify (sign another key to make it trusted)
A – authentication (log into SSH)

So your primary key is used for signing and the subkey is used for decrypting. There are some advantages to having them separate, mainly when it comes to revoking a key so others stop using it. There is not much of a reason to revoke the signing key but you might want to revoke the decrypting subkey to protect the encrypted data and create a new subkey.

The 40 character long string is the fingerprint of your primary secret key. It is a unique identifier. The subkey has its own, it is just not shown by default. You can display it by calling --list-keys with --with-subkey-fingerprint parameter.
There is also a creation date and an expiration date, if any.
The [ultimate] mark states the trust level. Since you created this key, you trust it ultimately. There is a whole system using a trust database trying to solve the problem of “Does this key really belong to the person it says or is someone trying to impersonate them?” but for the purpose of sharing data between few friends it can be safely ignored in my opinion.

The list of public keys looks the same. You will find there the primary public key which matches your secret key fingerprint and it also has its own public subkey.
In the public list there will also be the public keys of other people that you imported.

Viewing keys on disk

You can find your keys and other GPG related files at your home directory:

/home/(user)/.gnupg/

Some important files and directories:

The .gnupg directory should be owned by you, the user account. Pretty much all the files in there should be owned by you as well, with possible exception of secret keys generated by root, but the most important ones are the directory with secret keys, pubring.kbx, tofu.db and trustdb.gpg.
So, the owner should be you and should have permissions to read and write and the group should be you as well with permission to read at most. For others, they should not have more than a read permission, if any at all.

Working with individual keys

Most GPG commands can be supplied with an identification of a key the command should target. To specify the target key, you can use the key’s fingerprint (or just its last 16 characters, or just its last 8 characters) and you can also use the name or email in the key’s user ID.

Exporting keys

gpg --export (key name) > publickey.gpg gpg --export-secret-keys (key name) > secretkey.gpg

The public key is exported to publickey.gpg file. It is exported completely – the primary key and all subkeys in single file. You can share this file with other people.
It works similarly when exporting the secret key. When exporting, it asks you for password to decrypt the secret key. The resulting secret key file contains both the public key and the secret key. The secret key part seems to stay encrypted because you will get prompted to enter the password when importing it. Still, you should make sure that nobody else has access to this file. Be careful when you decide to export secret keys.

There are some additional options you have when exporting:

Importing keys

gpg --import keyfile.gpg

Signing files and text messages

gpg -s message.txt gpg --clear-sign message.txt

For signing a message, you have two options. First will result in a .gpg file which is the contents of message.txt combined with your signature and then compressed (but not encrypted).
The other option will result in .asc file which contains the same in uncompressed format (and so it is readable by human).

To sign files, you want to use this command which will result in .sig file which contains only the signature:

gpg -b file.exe

For all three signing commands applies that GPG will automatically select a secret key and ask you for password so it can be used to create the signature. If you have multiple secret keys, you can select the one you want to use like this:

gpg -u (key name) -s message.txt

Verifying signature

gpg --verify file.txt.gpg

Will use the right public key (if it exists in your pubring.kbx database) to verify the signature. It will tell you who made the signature, when it was made, it will calculate hash of the file and compare it with hash stored in the signature. If the signature is Good, everything is fine. If the signature is Bad, then it means that the file is not the same as the file that was signed. It might be modified by someone, it might be a completely different file or the signature file is damaged.

This can verify all three kinds of signatures. In case of the .sig signature file, beware that it will check integrity of a file of the same name in the same directory. So file.txt.sig will verify file.txt. If no such file exists, it will result in “no signed data”.

Encrypting files

gpg -e --recipient (public key name) file.txt

This will use specified public key to create an encrypted .gpg copy of the file. Only the public key’s owner can decrypt it (using their secret key). So when you want to send data to a friend, you use the friend’s public key here. If the public key has an “unknown” trust level, GPG will ask you for confirmation. If this bothers you, see Making public keys trusted.

You can combine encrypting and signing to produce single encrypted and signed .gpg file. Such file can’t be verified but it can be decrypted which will automatically verify it and remove the signature from decrypted output. The commands are:

gpg -s -e --recipient (public key name) file.txt

Decrypting files

gpg -d file.txt.gpg > file.txt

If the .gpg file was encrypted with your public key and you still have the corresponding secret key, this will decrypt the file and write the data to specified output file. If the file is signed, GPG will also verify the signature.

Making public keys trusted

gpg --sign-key (public key name) gpg --lsign-key (public key name)

This will use one of your secret keys (which are ultimately trusted) and add a signature to the public key which will result in the key showing up with full trust. This information is now part of the public key and when the key is exported, it will be exported too. When you send the exported key to someone, they will know that you signed it. If you don’t want that, use the second command. That works the same but the signature is kept in your trust database only.
You can choose what secret key to use to sign the public key like this:

gpg -u (secret key name) --sign-key (public key name)

If the public key still shows up as unknown, try updating the trust database:

gpg --check-trustdb

If it still doesn’t work, you can just set the public key as ultimately trusted using the edit key menu. First command opens the menu, then you command it to change trust level, set it to 5 and finally quit the menu:

gpg --edit-key (public key name) trust 5 y quit

Other considerations

Backing up and restoring keys

The most convenient way of backup is to make a copy of files in the .gnupg directory. That means the revocs and private keys directories, pubring.kbx, tofu.db and trustdb.gpg. There are other files in there, like socket files, but those don’t hold data.

For a minimal backup, you need only a copy of your key pairs. The rest can be created or obtained anew. You can extract your secret and public keys and save them somewhere in an encrypted archive, print them or use a smartcard. Potentially you could skip your public keys because you should be able to obtain them from places where you published them.

Sharing public keys

Whatever you do to send files to your friends will probably work fine. Moving it on a flash drive is fine, as is sending it through most applications that can send files. If you are worried about the possibility of the key being replaced by different one during transfer, you can always call them on a phone to check that the fingerprint matches.

If you want to share your key with a lot of people, look into the possibility of sending it to one or more key servers.

Don’t forget that when you update your public keys, you need to share them again.

Updating your keys

In case your user ID is no longer valid (changed the email address for example) you can update it by adding a new one, selecting the old one (after the “uid” command, an asterisk will mark the selected user ID) and revoking it:

gpg --edit-key (your key name) adduid uid (number of the old user ID, first is 1, second 2 etc.) revuid save

You can change expiration date of your keys in a similar way:

gpg --edit-key (your key name) key (number of the key/subkey you want to change, first is 1, second 2 etc.) expire save

Forward secrecy

It is about protecting past past communication and it is not supported by PGP. When someone is listening on your encrypted communication, saving the messages and after few years manage to get access to your secret key, they will be able to decrypt everything they intercepted.

Apart from never exposing your secret keys, the only thing that can be done about this is to keep creating new public encryption keys and deleting the revoked secret keys. Encrypted messaging applications do something like this automatically but with GPG you have to keep manually sharing updates to your public key, so you can’t do this too frequently.

Adding and revoking keys is the same as with user IDs. Use “gpg –edit-key” and then “addkey” to add and “key” to select subkey for revoke with “revkey”. Don’t forget to “save”.

Deleting secret subkey depends on GPG version, in newer versions (around 2.4.19 and newer) you can do (notice the exclamation mark):

gpg --delete-secret-keys (secret subkey fingerprint)!

In older versions that command will always delete primary key. Instead, you have to call gpg-agent and give it keygrip of the subkey (it is the same as the secret key’s file name without the .key extension):

gpg-connect-agent “delete_key (secret subkey’s keygrip)”

Privacy

If someone gets remote or physical access to your computer files, they won’t be able to use or change your secret keys, because they are protected by password. But they will see what public keys you have and possibly what secret keys you have too (after all, --list-secret-keys does not ask for password).
Sometimes that can be a problem, so in that case you will want to get some software to encrypt your home directory, or at least the .gnupg directory.

signature