Update 2023-04-04: Since writing this article, I’ve moved development to a MacBook and so I’ve found a few things I’d like to amend, mostly in regards to PIN entry. See below for more information.
If you’ve been working with Git professionally or just as a hobbyist, you might have come across signed Git commits. Essentially, you cryptographically proof that you were the one who authored and/or committed the changes. Public platforms, like GitHub, GitLab, etc. will mark your commits with a green checkmark. In case you are interested in how to do this, here is a short little cheat sheet that contains all the required commands. Use the Table of Contents to jump to the section you’re interested.
As time progresses, I might update this page and add a few additional commands if I come across some.
Setup
Packages / Programs
You will need the gpg package for your operating system. You’ll find it in your local package manager if it isn’t already installed.
If you are on Windows, install gpg4win. I recommend selecting Kleopatra in the installation wizard just so you get a nice graphical interface for setup. This guide will focus on the command line though.
Create keys
$ gpg --gen-key
Enter the requested details and add a password to protect it. When finished, you will get this output:
pub rsa3072 2022-03-15 [SC] [expires: 2024-03-14]
6F72[...]89B7
uid John Doe <j.doe@example.com>
sub rsa3072 2022-03-15 [E] [expires: 2024-03-14]
The string on the second line (6F72[...]89B7) is the thumbprint you can use to identify your key pair.
Import existing keys
In case you already have a key pair (i.e. generated and setup on another machine) you can export and re-import them on your other devices. For more information about exporting, check below. We assume that you have the two parts of your pair stored in separate files: public.key and private.key.
$ gpg --import public.key
$ gpg --allow-secret-key-import --import private.key
When importing your private key, you will be prompted to enter your keys password.
Set Git to sign your commits
Now, let’s set Git to always sign our commits. If you don’t want to sign all your commits, run the above command without the --global switch within your repository of choice.
$ git config --global commit.gpgsign true
Next, set the default key to sign commits:
$ git config --global user.signingkey 6F72[...]89B7
Other Operations
List Keys
$ gpg --list-keys
/home/user/.gnupg/pubring.kbx
-----------------------------
pub rsa3072 2022-03-15 [SC] [expires: 2024-03-14]
6F72[...]89B7
uid [ultimate] John Doe <j.doe@example.com>
sub rsa3072 2022-03-15 [E] [expires: 2024-03-14]
$ gpg --list-secret-keys
/home/user/.gnupg/pubring.kbx
-----------------------------
sec rsa3072 2022-03-15 [SC] [expires: 2024-03-14]
6F72[...]89B7
uid [ultimate] John Doe <j.doe@example.com>
ssb rsa3072 2022-03-15 [E] [expires: 2024-03-14]
Export Keys
$ gpg --export -a 6F72[...]89B7
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGIw4rYBDAC9e0ZnwcX7xNhYBKSclcYXHi/F4Uy69x3iba/PRhZPvYJ1TzED
[...]
=SsEI
-----END PGP PUBLIC KEY BLOCK-----
$ gpg --export-secret-key -a 6F72[...]89B7
-----BEGIN PGP PRIVATE KEY BLOCK-----
lQWGBGIw4rYBDAC9e0ZnwcX7xNhYBKSclcYXHi/F4Uy69x3iba/PRhZPvYJ1TzED
[...]
=+y/P
-----END PGP PRIVATE KEY BLOCK-----
Delete keys
In case you need to, here is also the command to remove both parts of your key pair from your keyring:
$ gpg --delete-secret-and-public-keys 6F72[...]89B7
PIN (Password) entry
By default, you will get a terminal-only PIN entry program so you will need to have a terminal session open to enter your password. Most IDEs will therefore fail to commit changes with Git. To get around this, you can substitute the provided PIN entry program with another one. (If you’re using Kleopatra, you can skip this section.)
On macOS, you can install pinentry-mac using the Homebrew (brew) package manager.
$ brew install pinentry-mac
==> Downloading https://formulae.brew.sh/api/formula.jws.json
[...]
After installation, you’ll need to configure gnupg to use pinentry-mac (or your PIN entry of choice) and restart the key agent.
$ echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.conf
$ gpg-connect-agent reloadagent /bye
Alternatively, edit/create the file ~/.gnupg/gpg-agent.conf and add the following line (ensuring the path to your PIN entry program is correct):
pinentry-program /opt/homebrew/bin/pinentry-mac