Why does one need a gpg key?
GPG keys have a bunch of good uses, what I use them for most is digitally
signing data (in my case git commits) which allows people to verify that a
commit was authored by me. If you look at my
commits to a repo, you should
see a Green Verified
badge next to each one.
This proves that I signed and pushed this commit. By default Git allows you to set the name and email for the author of a commit to whatever you want, so this is a good built-in way to authenticate that the committer is who they say they are.
Install gpg(2)
The first thing you need is to make sure you have gpg installed, and that
gpg --version
is at least 2.x
. You can get gpg
through your package
manager if it's not already on your system.
If your gpg --version
returns 1.x
, then see if you have a gpg2
. If gpg2
returns 2.x
, then you're fine, just use gpg2
wherever I used gpg
.
Generate your key
First work out what you want your name and email address to be. I recommend keeping them the same as your Git name and email address.
So first check what Git thinks your name/email is with:
git config --global user.name
git config --global user.email
Then generate a key:
# Use `gpg2 --gen-key` if `gpg` is version 1.
gpg --gen-key
- Real name: paste in your Git user.name, e.g.:
Gibson Fahnestock
- Email address: paste in your Git user.email, e.g.:
gibfahn@gmail.com
- Passphrase: You don't normally change this, so pick a good password (enter twice).
Once this is done you should have a new key in your keyring. Check it with:
$ gpg --list-keys
/Users/gib/.gnupg/pubring.gpg
-----------------------------
pub 4096R/821C587A 2016-10-07
uid [ultimate] Gibson Fahnestock <gibfahn@gmail.com>
sub 4096R/2C482931 2016-10-07
Telling Github/Github Enterprise/Gitlab about your key
In the same way you'd add an ssh key, you can add a gpg key in your settings. Go
to your key settings and click on
New GPG key
.
To print your public key do:
# If you chose a different email, use it instead of the $().
gpg --armor --export $(git config --global user.email)
then paste that key into the Github/lab entry box.
Telling git to sign commits:
You can tell git to sign all commits by default with:
git config --global commit.gpgsign true
However I've removed this from my dotfiles, as
it caused problems with some test suites (e.g. the npm test suite), and also
caused problems on older machines that don't support the gpg option (or that I
haven't set up my gpg keys on). Instead I just add -S
to all my git commit aliases,
which also means that if I don't want to sign something I can just type out the
full command.
Remembering your password:
Having to type out your gpg password every time is a massive pain, so you
probably want your OS to store your password in your login keychain when you're
logged in, so you only have to enter it once. With gpg2
on Linux or macOS this
is easy.
Linux
I currently use Ubuntu with bspwm, so if it works for me it'll probably work for you. Let me know if it doesn't!
If your default gpg
is gpg2
, you can either tell git to use gpg2
rather
than gpg
, or you can make gpg
point to gpg2
. See this commit
for my reasoning (short answer is because I want my git config to work
everywhere).
Option 1: tell git to use gpg2
:
git config --global gpg.program gpg2
Option 2: change your default gpg
(more info here):
sudo mv /usr/bin/gpg /usr/bin/gpg1
sudo update-alternatives --verbose --install /usr/bin/gpg gnupg /usr/bin/gpg2 50
macOS
You need to configure gpg to use pinentry-mac
to read your gpg password from
the macOS keychain. For more information see gpg pinentry SO.
First, install gpg and pinentry-mac
:
brew install gnupg pinentry-mac
Second, configure gpg to use pinentry-mac
to get the password.
# Set GNUPGHOME in your rc file so gpg reads it.
mkdir -p "${GNUPGHOME:="${XDG_DATA_HOME:-~/.local/share}"/gnupg}"
echo "pinentry-program /usr/local/bin/pinentry-mac" >> "$GNUPGHOME"/gpg-agent.conf
Make sure it works:
If you try a commit (git commit -m "DeleteMe" -S
, make sure you're in a git
repo) you should get a password prompt, and if you do another (git commit --amend --no-edit -S
) it should have remembered your password.
If you push to GitHub or GitLab, you should see the green checkmark.
Troubleshoooting:
If it fails you can check whether gpg is working properly by setting:
export GPG_TTY=`tty`
This tells gpg
to use your terminal to prompt for your password. If gpg only
works when you set this then your gpg agent is probably configured wrong.
If this doesn't work, git
is probably confused about which key to use. You can
set the default in ~/.gnupg/gpg.conf
, or just tell git about your key with:
gpg --list-keys
# I get the following output:
# /home/gib/.gnupg/pubring.gpg
# ----------------------------
# pub rsa4096/821C587A 2016-10-07 [SC]
# uid [ultimate] Gibson Fahnestock <gibfahn@gmail.com>
# sub rsa4096/2C482931 2016-10-07 [E]
# Copy the key ID, in my case 821C587A:
git config --global user.signingkey 821C587A # Use the ID from above.