GPG is a very complex tool. However, to sign git commits you only need a handful scope of it. This post will show you how to set up and manage your GPG keys with ease.
When you commit something, Git inserts your name and email in the commit message.
Check my other post on how to elaborately setup different accounts for different folders.
In short, these params are taken from a config file or environment variables. This means that anybody can make a commit with your name and email and no one will be able to make a difference between you and the scammer.
This is a problem especially in huge Open Source projects: hackers really want to sneak commits into theirs source tree.
🔗How can GPG help?
GPG allows us to confirm that commits were made by who we think made them. Asymmetric cryptography is awesome! To use it, you will need to generate two keys : public and private. Git will then sign your commits with the private key. The public key needs to be uploaded somewhere:
- to Github/Gitlab account
- a keyserver (like pgp.mit.edu or keyserver.ubuntu.com)
- posted on your webpage
Anybody will be able to verify that the signature is valid. SCMS can do this automatically, since you’ve uploaded your public key there. That’s why you can see the “Verified” label next to some commits:
One other feature is that you can enable “All commits must be signed” options in your SCMS, so nobody will be able to mimic you .
🔗How to set it up?
I’m using Fish shell, but it should be easy to port these code snippets to the shell of your choice.
First, we need to help GPG to correctly detect a TTY.
set -x GPG_TTY (tty)
In most cases, this is not needed. However, termux environment on my Android phone required this.
Now we can generate the keys:
This will launch the prompt that will ask you all needed parameters. Unlike other commands you may find, this one will allow you to configure an expiration date.
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) (14) Existing key from card Your selection?
The default option is good enough
RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072)
I see no reason not to set it to 4096 to max out securrrrity 😎
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
I prefer to make unexpired keys
- The last two questions are about your real name and email. Use the same ones you use in git.
Now when the generation is complete you can view your keys with this command:
The long number here (
5490…) is a key identifier. It will be used a lot, so take a note of it.
Okay, now we can get and upload our public key:
This will print out a huge key. Just copy and paste it to your SCMS.
You can already start using it with git. To create a signed commit:
To sign all commits by default:
If your Git user differs from the GPG email, you can tell Git explicitly which key to use:
Cool! Are we done? Not quite!
Always backup your keys!
🔗Backup and restore keys
GPG won’t let you just view the private key. They are stored in a vault (
~/.gnupg/pubring.kbxby default). However, backing up the vault is not recommended: it contains not only your keys, but others that your system trusts:
If you will just replace this file on a new system, a lot of things might break!
The proper way to do this is to export your keys first:
Then you can import them:
🔗Transfer keys to another machine~/.config/yadm/encrypt
… .gnupg/export/* …
Now you can run
It will take all files listed in
~/.config/yadm/encryptand put them into
.local/share/yadm/archive. This archive can then be synced safely.
On the target system you run
and enter you passphrase to extract files from the archive back to their directories.
to import it to your keystore.
I use these fish functions that help me automate some routine:.config/fish/conf.d/gpg.fish
set -x GPG_TTY (tty) function gpg-export mkdir ~/.gnupg/export gpg -a --export-secret-key -o ~/.gnupg/export/private-key.asc end function gpg-import gpg --import ~/.gnupg/export/private-key.asc end function gpg-ls gpg --list-secret-keys --keyid-format LONG end function gpg-get gpg --armor --export $argv end
The function names should be self-explanatory.
Hope this helped you to secure your online presence :) Stay safe!