GPG for GitHub
Posted on November 5, 2024 • 3 min read • 515 wordsGPG, or GNU Privacy Guard, is a free-software replacement for Symantec’s PGP cryptographic software suite. GPG is not a new cryptographic algorithm. GPG keys are simply those generated by the GPG software using existing algorithms such as RSA.
gpg is a CLI tool for managing keys, and the keys it generates have more features. For example, GPG keys can
expire or be revoked. With GitHub, SSH keys are used for authentication, while GPG keys are used for
signing commits and tags. Commit-signing makes sure the committer is indeed who he/she claims to be —
otherwise any one can claim to be any one by setting username and password with git config.
Installing GPG
brew install gnupgInstalling pinentry-mac
pinentry-mac is a GUI for prompting for passphrases.
brew gnupg pinentry-mac
echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.confRestart gpg-agent.
gpg-connect-agent reloadagent /byeManaging GPG Keys
The commands in this section applies to gpg version 2.1.17 or greater.
List existing keys
gpg --list-secret-keys --keyid-format=longIf the output of the command above is something like,
/Users/hubot/.gnupg/secring.gpg
------------------------------------
sec 4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
uid Hubot <hubot@example.com>
ssb 4096R/4BB6D45482678BE3 2016-03-10the $KEYID that we can use in most other commands is 3AA5C34371567BD2.
Export public key to base64-encoded format
gpg --armor --export $KEYIDThe output can be copy-pasted to GitHub web UI. For signing purposes, public key suffices.
Generate a new key
gpg --full-generate-key- For the “kind” of key, “RSA (sign only)” is enough for signing commits and tags.
- For expiration, GitHub recommends taking the default of no-expiration date.
- For email address, use one that has been verified with the GitHub account.
- Passphrase won’t be a hassle. Many Linux desktops offer to store it in a password manager.
Export/import public and private keys
The above base64-encoded export format is readable text and suitable for copy-pasting into GitHub web UI. To transfer keys across machines, we should export and import them in raw binary format.
To export:
gpg --export $KEYID > public.key
gpg --export-secret-key $KEYID > private.keyTo ZIP them with encryption:
zip -e gpg.zip public.key private.keyTo import on the target machine:
gpg --import public.key
gpg --import private.keyConfigure git to use key
To use a specific key:
git config --global user.signingkey $KEYIDSign with git
To sign a commit:
git commit -S -m "YOUR_COMMIT_MESSAGE"To sign a tag:
git tag -s $MYTAGTo sign all commits by default:
git config --global commit.gpgsign trueSign with a GPG key stored on Yubikey
Enter GPG interactive mode by gpg --card-edit, and then enter the fetch and quit command in order.
The outputs would be something like below.
gpg/card> fetch
gpg: requesting key from 'https://github.com/kxue43.gpg'
gpg: key C9EED408F4B6D021: "Ke Xue (kxue43.github.io) <xueke.kent@gmail.com>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
gpg/card> quitThen use gpg --list-secret-keys to confirm that the keys have been fetched.
The outputs should be something like below.
[keyboxd]
---------
sec> rsa4096 2025-12-24 [SC]
5EF2BE73370DCE7E808814DBC9EED408F4B6D021
Card serial no. = 0006 27538718
uid [ unknown] Ke Xue (kxue43.github.io) <xueke.kent@gmail.com>
ssb> rsa4096 2025-12-24 [E]