Use GPG to sign, verify, encrypt and decrypt files, emails, and commits

Last update: 11/15/2022

What is GPG? ​

"GnuPG is a complete and free implementation of the OpenPGP standard as defined by RFC4880 (also known as PGP). GnuPG allows you to encrypt and sign your data and communications; it features a versatile key management system, along with access modules for all kinds of public key directories. GnuPG, also known as GPG, is a command line tool with features for easy integration with other applications [...]"

GPG website

GPG (GnuPG, open source) is different from PGP (proprietary). It primarily uses private/public keys to handle all encryption/decryption/sign/verify actions (you can also use symmetric, but isn't so fun).

Generating your GPG key ​

bash
gpg --full-gen-key

# For older versions (including Windows and MacOS) you can use --gen-key if the parameter above fails
  1. Select the algorithm (use the default RSA and RSA);
  2. Specify the length (longer = better, currently you will find 4096-bit);
  3. Most of the times you don't need to select a validity period (better if you set a shorter period in case of leaks, but inconvenient sometimes);
  4. Type your full name and email when prompted;
  5. You may add a comment (usually shown close to your name/email);
  6. You will be asked for a password, use a strong one;

Time to list the GPG keys generated and saved at your profile:

bash
gpg --list-secret-keys --keyid-format LONG <EMAIL USED TO GENERATE THE KEY>

# The output will look like this (this example shows two keys):
#
# gpg: checking the trustdb
# gpg: marginals needed: 3  completes needed: 1  trust model: pgp
# gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
# gpg: next trustdb check due at 2024-11-15
# /home/user/.gnupg/pubring.kbx
# ------------------------------
# sec   rsa3072/CXXXXXXXXC540 2022-01-01 [SC] [expires: 2024-01-01]
#       4285ECCCCCCCCCCCCCCCCCB4C48AFCXXXXXXXXC540
# uid                 [ultimate] Your name <email@example.com>
# ssb   rsa3072/F3DC33A661677229 2022-01-01 [E] [expires: 2024-01-01]
#
# sec   rsa4096/84YYYYYYYYYYE 2022-01-01 [SC]
#       78C4E82E42C7AA5535B1233320ED984YYYYYYYYYYE
# uid                 [ultimate] Your name <email@example.com>
# ssb   rsa4096/A7CCCCCCCCCC5214 2022-01-01 [E]

The ID, refered at the next commands, is the string after the / (E.g. CXXXXXXXXC540)

Exporting the GPG public key ​

Likely you will have to sent your PUBLIC key to someone, or store it at some system for the purposes listed later. To export as text, use the export parameter:

bash
gpg --armor --export <ID>

# The output looks like this (always copy the key including the BEGIN and END lines):
#
# -----BEGIN PGP PUBLIC KEY BLOCK-----
#
# mQINBGN0XVIBEACgiLew1ciXwpKyLZqVMGJ/c70y7RyyrloQswm9rPdrJTIprDpk
# [a bunch of characters here]
# =R8RB
# -----END PGP PUBLIC KEY BLOCK-----

Remember: The Public key can be shared with anyone, the Private key should NEVER leave your pc, keep it secret.

You can also export it to a .gpg file, useful to skip the copy/pasting step:

bash
gpg --armor --output <FILENAME>.gpg --export <ID>

Using GPG to sign up commits ​

You may sign just a few commits, using the -S flag:

bash
git commit -S -m "Your regular commit message"

Or all commits, using the global config:

bash
git config --global commit.gpgsign true

# Now all following commits will include the signature

If you find problems with the signature, try using gpg2 instead. Set for all repositories using git config --global gpg.program gpg2

Using GPG with GitLab ​

GitLab will show a verification badge next to signed commits. See the GitLab documentation for details.

You can find a user's GPG public key at https://gitlab.com/<username>.gpg.

Using GPG with GitHub ​

GitHub will show a verification badge next to signed commits. See the GitHub documentation for details.

Importing other users public keys to your profile ​

When encrypting or verifying a file's signature, ask for the recipient's public key and import it:

bash
# Import the received key from a file, such as the generated `.gpg` file
gpg --import recipient-pubkey.gpg

Using GPG to encrypt/decrypt files ​

Encryption uses the recipient's public key. Only the recipient can decrypt the file with their private key. You can encrypt only one file at a time, including a text file or another format such as .tar.gz.

Make sure to import the recipient public key before running the command

bash
gpg --output encrypted-file.txt.gpg --encrypt --recipient recipient@example.com file.txt

To decrypt, your peer must simply execute:

bash
gpg --output file.txt --decrypt encrypted-file.txt.gpg

The command above will use the private key in order to decrypt the file.

Using GPG to sign/verify files ​

Generating a signed file is similar to encrypting a file, but uses the --sign command. GPG uses your private key to sign the file.

bash
gpg --sign somefile.txt

It will generate a file with .gpg extension, containing the file and your signature.

To verify the file's integrity, use --verify. This command uses your public key to check the file.

bash
gpg --verify somefile.txt.sig

You can also see the contents of the file using --decrypt:

bash
gpg --output file.txt --decrypt signed-file.txt.gpg

Remember that decryption uses the sender's public key, so the file contents are not hidden from anyone who has your public key. Public keys are meant to be shared.

Sign up or encrypt emails using GPG ​

You can also use GPG to sign or encrypt email. Thunderbird is a suitable tool for this. See the Thunderbird documentation for information about configuring the client.

Note that most webmails (including Gmail) do not provide a client that can handle GPG. Your private key should never leave the safe place (your laptop). You can use Thunderbird to send/receive end-to-end encrypted emails via IMAP/SMTP/POP for supported providers.

Set default GPG key on Debian/Ubuntu ​

If you have multiple keys you can set your default key creating/updating the file ~/.gnupg/gpg.conf:

bash
# First list all keys
gpg --list-signatures

# Create file using vim/nano/anyother editor
# ~/.gnupg/gpg.conf
# and include the contents
# default-key YOURIDHERE

If you don't set the default one, the first generated is usually the default.