Git Commit Signing with GPG & YubiKey
Table of Contents
After learning about how GitHub displays names and profile pictures next to commits, and how this mechanism can be abused rather easily, I decided to enhance the integrity of my public-facing activity on GitHub by attaching digital signatures to my commits.
This document is a summary of all of the online resources I used to set-up my GPG key pair to work seamless across my machines, my YubiKey hardware-based security key and on GitHub. I used my name and email for demo purposes only, which means that if you copy my details and use them in your key pair, it will look goofy in your commit log.
Required Software #
git
gpg
- YubiKey Manager
- A GitHub account
Generate Key Pair #
The key pair first has to be generated on your local machine, such that its metadata is associated to your GitHub account’s public-facing details, and its cryptographic algorithm is suitable to your requirements.
According to GitHub’s GPG keys Guide1:
Generate a key pair.
- Make sure to specify your preferred cryptosystem algorithm and your
gitconfig
contact details
$ gpg --full-generate-key
- Make sure to specify your preferred cryptosystem algorithm and your
Get your key ID:
$ gpg --list-secret-keys --keyid-format=long sec> rsa4096/4DAFB02B4734FE52 2021-09-01 [SC] ________________________4DAFB02B4734FE52 # ... uid [ultimate] Omri Bornstein <omribor@gmail.com> ssb> rsa4096/422B0DEA5FB23439 2021-09-01 [E] $ export KEY=________________________4DAFB02B4734FE52
Print your public key:
$ gpg --export --armor $KEY -----BEGIN PGP PUBLIC KEY BLOCK----- # ... -----END PGP PUBLIC KEY BLOCK-----
Copy your public key, beginning with
-----BEGIN PGP PUBLIC KEY BLOCK-----
and ending with-----END PGP PUBLIC KEY BLOCK-----
.Follow GitHub’s guide to add your public key to your account.
Back-up Your Key Pair #
You can export an ASCII text version of your private key in case you wish to have a back-up version available at a secure location.
$ gpg --export-secret-key --armor $KEY
-----BEGIN PGP PRIVATE KEY BLOCK-----
# ...
-----END PGP PRIVATE KEY BLOCK-----
Enable Commit and Tag Signature #
You can enable commit signing by default by editing your ~/.gitconfig
file. Your details must match to the details you provided when creating your key pair.
[user]
name = Omri Bornstein
email = omribor@gmail.com
[commit]
gpgSign = true
[tag]
gpgSign = true
Graphical PIN Entry #
By default, gpg
asks for your key’s PIN to be entered to its command-line prompt before the private key is used for signing. In case you want to use GPG from a non-TUI environment, the Arch Linux wiki covers how to enable PIN entry from a graphical interface.
Import Key Pair to YubiKey #
At this point, you can utilise your key pair from your local machine with git
perfectly fine in such a way that GitHub will display a verified badge next to your commit messages. In case you have a OpenPGP-capable hardware-based security key, you can optionally move your key pair to it, such that it can be used seamlessly and securely across machines.
Tom Stuart has an awesome video on YouTube2 showing how ot transfer a key pair to a hardware-based security key like a YubiKey. A similar guide can be found in a written form on @drduh
’s YubiKey guide[^4].
Connect your YubiKey to your machine.
gpg
lists each of the keys in the key pair according to their role. The first-listed key is intended to be used for digital signatures (labeled by[SC]
), and the second-listed key is meant to be used for encryption.$ gpg --edit-key $KEY sec> rsa4096/4DAFB02B4734FE52 2021-09-01 [SC] ________________________4DAFB02B4734FE52 # ... uid [ultimate] Omri Bornstein <omribor@gmail.com> ssb> rsa4096/422B0DEA5FB23439 2021-09-01 [E]
Select each key and instruct
gpg
to move it to the appropriate key slot on the YubiKey.gpg> key 0 gpg> keytocard Please select where to store the key: (1) Signature key (3) Authentication key Your selection? 1 gpg> key 1 gpg> keytocard Please select where to store the key: (2) Encryption key Your selection? 2
Make sure to save the changes and exit the
gpg
command prompt.gpg> quit Save changes? (y/N) y
Add YubiKey-backed Key Pair to Another Machine #
In case you want to use the same YubiKey across multiple machines, @drduh
’s YubiKey guide3 covers how to inform gpg
(installed on another machine) of the key pair you already transferred to your YubiKey from a different machine.
From the original machine with your YubiKey plugged-in, you’ll need to make a copy of the public key alongside a list of the trusted GPG keys.
$ gpg --export --armor $KEY > gpg-public-key-$KEY.asc
$ gpg --export-ownertrust > gpg-owner-trust.txt
Copy both files to the second machine (with gpg
installed). Then, on the second machine:
Define your KEY. For example:
$ export KEY=________________________4DAFB02B4734FE52
Import your public key:
$ gpg --import gpg-public-key-$KEY.asc
Import the trust settings:
$ gpg --import-ownertrust < gpg-owner-trust.txt
Insert your YubiKey into a USB port.
Import the private key stubs from the YubiKey:
$ gpg --card-status # ... Application type .: OpenPGP Version ..........: 2.1 Manufacturer .....: Yubico # ...
Now you can use the YubiKey on your multiple machine seamlessly.
Result #
Git will now use the key pair stored on your YubiKey, and attach a digital signature to all future commits issues from your machine. As a result, GitHub will show a verified badge in the commit’s details page, showing your fellow contributors the integrity of the identity shown in relation to the changes you made (like in commit 74f9009
from raker
). Similarly, the git verify-commit
and git verify-tag
commands can be used locally to ensure your digital signature is recognised as valid by Git.
$ git verify-commit 74f9009
gpg: Signature made Sat 30 Dec 2023 20:48:50 AEDT
gpg: using RSA key ________________________4DAFB02B4734FE52
gpg: issuer "omribor@gmail.com"
gpg: Good signature from "Omri Bornstein <omribor@gmail.com>" [ultimate]
GitHub. (2016). Generating a new GPG key. GitHub Docs. https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key ↩︎
Stuart, T. (2022). How to set up Git commit signing with GPG and a YubiKey on macOS [YouTube Video]. In YouTube. https://youtu.be/7LuMTyhFA-g ↩︎
drduh/YubiKey-Guide
(2023). Guide to using YubiKey for GPG and SSH. (2023). GitHub. https://github.com/drduh/YubiKey-Guide?tab=readme-ov-file#multiple-hosts ↩︎