Getting started with GPG keys

No matter how hard you try, sometimes you need to share some form of secret with someone. It may be a new password for a user, a password for some service that a team-mate needs access to, or an API key someone needs for some tool they’re developing. Encrypting with a GPG key is simple and secure way to do this.

There are plenty of hacky ways to get this information over (partial messages over various channels, emails with no context, etc.), but asymmetric encryption with good secrets is a great way to transmit sensitive information.

If you’re very new to the ideas of public key encryption, this analogy is pretty useful.

Disclaimer: this process is aimed at Linux users. YMMV on MacOS with brew, and I’ve no idea how to help you with Windows.

Getting set up

First up, you’ll need to install the required packages:

sudo apt install gnupg

Quick aside on nomenclature: gnupg (GNU Privacy Guard) implements the OpenPGP standard

Rolling a new pair of keys

Now generate a new GPG key pair with:

gpg --full-generate-key

Specify the key type you want, make the size 4096 bits (size does matter here), add an expiry date if you want.

When you add your email address, if you’re planning to use this key for signing Git commits, make sure you use the email address you verified with your Git provider, or the no-reply address they provided you (if you want to keep your email address secret).

Next use a really good passphrase.

Propagating your public key

A public key is exactly that - something that can be made public. Your public key can be used by someone to encrypt a message they wish to send you. Only your private key can decrypt messages encrypted with your public key. You must make sure your private key never gets shared.

It’s safe to make your public key available over email, Slack, etc.

Extract your public key:

gpg --armor --output mypubkey.gpg --export your.name@example.com

The email address here is the one you used when generating the key.

The --output flag specifies the filename to save the key.

GPG keys are binary by default. The --armor flag encodes the binary to a text format that can be shared over email, etc.

Encrypting a message

Now your colleague is armed with your public key, they can encrypt a message for you.

Firstly, they must import the key to their keyring, once they’ve saved it as received_pubkey.gpg:

gpg --import received_pubkey.gpg

To encrypt a file supersecret.txt with your key, they will run:

gpg --output supersecret.txt.gpg --encrypt --recipient your.name@example.com supersecret.txt

They can now freely share supersecret.txt.gpg with you (email, Slack etc.)

Decrypting a message

Once you have this file, you can decrypt it with:

gpg --output supersecret.txt --decrypt supersecret.txt.gpg

Listing keys in your keyring

You can see the keys you have in your keyring with:

gpg --list-keys --keyid-format LONG --fingerprint

Signing Git commits

This is the cool bit. You can sign your commits to a git repository automatically. Signing is a form of encryption, and allows recipients to be sure of who has provided an encrypted payload.

To configure git to sign commits, you firstly need the key ID you wish to sign with:

/home/username/.gnupg/keyring.gpg
------------------------------------
sec   4096R/3AA5C27561567BD2 2020-05-02 [expires: 2021-05-02]
uid                          Your Name <your.name@example.com>
ssb   4096R/93B327EA9BA89E7A 2016-05-02

The ID here is the part 3AA5C27561567BD2 on the line beginning sec.

Update your git config to use this key:

git config --global user.signingkey 3AA5C27561567BD2

Note: you can add this per repository if you’re using different keys

You also need to add the key to your .bashrc or .profile:

echo "export GPG_TTY=$(tty)" >> ~/.bashrc && source ~/.bashrc

GitHub and Gitlab have posted instructions for adding your keys to your account.