Signed commits with GPG and GitHub on Linux
Start by installing the latest version of GnuPG2.
sudo apt update
sudo apt install gnupg2
Next, you need to generate a secret key. To generate a key, use the following command:
gpg2 --full-gen-key
This will start a step by step process of generating the key. You will be prompted to provide values for key type, key size and expiry details, before verifying the details. Finally, you will be prompted for personal details, such as real name, email address and an optional comment.
Keep in mind that generating the key will require a lot of entropy for the random number generator, hence you are encouraged to provide the computer with a lot of I/O, by using the keyboard, mouse, disk drives and network card. Patience is required. Here is an example key generation session:
gpg2 --full-gen-key
gpg (GnuPG) 2.1.11; Copyright (C) 2016 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: Full Name
Email address: full.name@email.com
Comment: some comment
You selected this USER-ID:
"Full Name (some comment) <full.name@email.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
After generating the key, you can start setting up Git to use the GPG key. First, you need to get the key ID by issuing the following command:
gpg2 --list-keys
Copy the part after rsa4096
, which is 40339211 in the example output below.
pub rsa4096/40339211 2016-08-13 [SC]
uid [ultimate] Real Name (some comment) <real.name@email.com>
sub rsa4096/EFFE1642 2016-08-13 [E]
Tell Git to use the new key, as well as specifying to use gnupg2:
git config --global user.signingKey <KEY_ID>
git config --global gpg.program gpg2
Additionally, you want to add use of the GPG agent when possible, so ensure the line "use-agent" is present in ~/.gnupg/gpg.conf
. You can check if it is present with the following snippet:
grep use-agent ~/.gnupg/gpg.conf
Committing with signature
Now you're set to try committing with the use of GPG signatures. To sign a commit, you really just need to add the -S
flag when committing:
git commit -S -m "Testing GPG signature"
This should invoke a prompt from the keychain/keyring on your machine requesting you type in the password you used when creating the key. The gpg-agent should keep your signature cached for a short while. To verify that it worked, you can fetch the latest commit hash by typing git log
and copying the hash. Paste the hash into the following command:
git verify-commit <commit_hash>
If it everything worked, you should see something like this:
$ git verify-commit c97dd2f5be0f1c3ce220db3e542b6fe41b957ee3
gpg: Signature made Fri 12 Aug 2016 08:58:33 PM CEST using RSA key ID 40339211
gpg: Good signature from "Real Name (some comment) <real.name@email.com>" [ultimate]
If you run into issues when trying to sign your commit. Slap on GIT_TRACE=1
before the git command. You should be able to extract the gpg command being used in order to further debug.
If it's not a bad key, but i.e bad ioctl device, make sure you set the tty: export GPG_TTY=$(tty)
. You might want to put that in your .bashrc
.
But you really don't want to have to specify the -S
flag each time, so you can enable it by default by issuing the following command:
git config --global commit.gpgSign true
Adding your public key to GitHub
Finally, you need to generate a public key from the secret key and add it to GitHub.
gpg2 --list-secret-keys --keyid-format LONG
As with the previous time you copied a key id, copy the part after rsa4096/
, and then use it to issue the following command, which will generate a public key.
gpg2 --armor --export 3AA5C34371567BD2
This will print out the public key to the terminal. Copy the contents, including the --- BEGIN ---
and --- END---
tags, and perform the steps explained in Adding a new GPG key to your GitHub account, from the official GitHub docs.