在 Github 使用 GPG 签名指南
在 Github 中 commit 启用 GPG 签名,显示尊贵的 `verified
GPG(GNU Privacy Guard)#
GPG(GNU Privacy Guard) 是一套基于 OpenPGP 标准(RFC 4880) 的加密与签名工具,广泛用于数据加密、身份认证与内容签名。它是自由软件,是 PGP(Pretty Good Privacy)的开源替代方案。
基本原理#
GPG 使用 非对称加密算法,即:每位用户拥有一对密钥:
- 公钥(Public Key):可以公开分享,供他人使用。
- 私钥(Private Key):必须妥善保管,仅用户本人持有kkk
根据上面的机制,,我们可以实现两大重要功能
- 加密: 发送者用你的公钥加密 → 只有你能用私钥解密
- 数字签名: 你使用私钥签名,别人通过公钥就可以验证这是你签发的内容
常见的用途:
- Git 提交签名(验证代码作者身份)
- 软件发行签名(验证发布包完整性与合法性)
- 加密通信(通过邮件或文件传输加密数据)
- 身份认证(作为安全凭证的一部分)
简单来说,GPG 为我们提供了一个非常炫酷的「数字签名」方式。
Github 中使用 GPG#
在参与开源项目的时候,都会要求贡献者使用 GPG 签发自己的 commit,以认证自己的代码提交记录,使用 GPG 签名的 commit 在 Github 中会有炫酷的 verified
字样:
展开就会看见详细的签名信息:
生成新的 GPG 密钥对#
首先我们要下载生成密钥对所需要的 GPG 命令行工具 ↗,或者是下载对应操作系统的 GUI 客户端(windows) ↗.
这里我们使用 Linux 命令行工具 gpg
最简单的安装方法(直接通过包管理器安装),当然了我们能使用最新版本的最好,一般通过包管理器拉下来的版本都比较落后。
这里的机器是 Ubuntu-22.04
:
sudo apt install gpg
bash安装完毕之后,使用以下命令开始生成新的 GPG 密钥对 (version > 2.1.17):
gpg -full-generate-key
bash接下来的步骤包含许多需要我们选择的配置,(签名算法等等):
$ gpg --full-generate-key
gpg (GnuPG) 2.4.7-unknown; Copyright (C) 2024 g10 Code GmbH
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
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
(14) Existing key from card
Your selection?
Please select which elliptic curve you want:
(1) Curve 25519 *default*
(4) NIST P-384
(6) Brainpool P-256
Your selection?
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: erasernoob
Email address: erasernoobx@outlook.com
Comment:
You selected this USER-ID:
"erasernoob <erasernoobx@outlook.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.
bash上述流程包含以下几个步骤:
- 选择我们需要哪种具体的 key
Enter
选择默认ECC
- 选择 key 的大小
Enter
选择默认 - 选择密钥的过期时间
0
为永不过期 - 确定配置是否完成
- 配置你的个人信息
- 用户名(随便填)
- 邮箱(如果要使用 Github 那么就一定要填写在 Github 上已经验证的邮箱,这样 Github 才能验证你的身份,以及 commit 收集)
- 配置完成,最终会通过 GUI 窗口的形式弹出对话框填写你的
Passphrase
非常重要,每次使用都需要填写
填写完毕之后,公钥和密钥就生成完毕了:
gpg: /c/Users/admin/.gnupg/trustdb.gpg: trustdb created
gpg: directory '/c/Users/admin/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/c/Users/admin/.gnupg/openpgp-revocs.d/342A3A02ADE7ED544D25A8E5828136735CCFD941.rev'
public and secret key created and signed.
pub ed25519 2025-06-13 [SC]
342A3A02ADE7ED544D25A8E5828136735CCFD941
uid erasernoob <erasernoobx@outlook.com>
sub cv25519 2025-06-13 [E]
bash以上就会自动生成 GPG 密钥信息,有以下部分组成:
pub
主公钥ed25519
主密钥算法2025-06-13
创建日期SC
此密钥用途:Signing(签名),Certification(认证)342A...FD941
密钥指纹(fingerprint)(40 位)uid
用户IDsub
子密钥,cv25519 用于加密([E])
以上密钥指纹中,我们需要的是 Key ID
也就是指纹的最后16位,我们可以使用以下的命令让 gpg 以长 id 的形式打出:
gpg --list-secret-keys --keyid-format=long
bash命令结果会以长 ID 形式打印出所有当前的 GPG 密钥对信息:
$ gpg --list-secret-keys --keyid-format=long
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
[keyboxd]
---------
sec ed25519/828136735CCFD941 2025-06-13 [SC]
342A3A02ADE7ED544D25A8E5828136735CCFD941
uid [ultimate] erasernoob <erasernoobx@outlook.com>
ssb cv25519/8FC6A81A9304953C 2025-06-13 [E]
bash也就是说我们需要的 Key ID
就是 828136735CCFD941
导出公钥#
gpg --armor --export 828136735CCFD941
# Prints the GPG key ID, in ASCII armor format
bash使用上面获得的 Key ID
,我们就可以需要交给对方的公钥:
-----BEGIN PGP PUBLIC KEY BLOCK-----
......
CAsCBBYCAwECHgcCF4AACgkQgoE2c1zP2UEzJAEA54H9E64Neti+D2lGwI1kpmGU
LtuM663assOrBDT7zskA/jQVb7dGff5QF+lFr9SMmVEzZaccoDfU/x3lvnoR/CQG
uDgEaEw01hIKKwYBBAGXVQEFAQEHQKjkXsddomXdvucO8wlm/f7HQirWEco2KBW8
yusqMsVqAwEIB4h4BBgWCgAgFiEENCo6Aq3n7VRNJajlgoE2c1zP2UEFAmhMNNYC
GwwACgkQgoE2c1zP2UECUwEAy3y4GrPxcI1icxErmnIlvow/afPucmuFCFTuh6r2
efgA/jsWXHso2n0Bi6YvEgx3APwNRcdZk9DaAl6Z5A0hrGQC
=65Yz
-----END PGP PUBLIC KEY BLOCK-----
bash配置 Git GPG 签名#
获得上述的公钥以后,我们需要将其上传到 Github 中。
你需要用 key ID
git config --global user.signingkey 828136735CCFD941
bash如果你希望 Git 自动使用 GPG 签名提交:
git config --global commit.gpgsign true
git config --global gpg.format gpg
# 始终添加 Signed-off-by
git config --global format.signoff true
bash签名命令示例#
git commit -S -m "Add new feature"
git tag -s v1.0.0 -m "Release v1.0.0"
bash这下你的数字签名就制作完成了.
迁移设备密钥对#
当拥有了多台设备进行主力开发,或者是需要切换到多个环境,比如 devcontainer 等等。但是再次配置一个新的 GPG 密钥又显得相对比较繁琐,所以我认为后续直接迁移已有的密钥对更加方便。
-
首先,在原设备导出 GPG 私钥
bash# 查找对应的密钥 ID gpg --list-secret-keys --keyid-format LONG
会出现类似下面的输出:
bashsec rsa4096/ABCDEF1234567890 2024-01-01 [SC] ... uid [ultimate] Your Name <you@example.com>
后面那串长哈希值,就是对应的 KEY ID
接着导出私钥:
bashgpg --export-secret-keys ABCDEF1234567890 > private.key # 导出公钥 (optional) gpg --export ABCDEF1234567890 > public.key
-
在新设备中导入私钥
bashgpg --import private.key # import private gpg --import public.key # optional
-
导入私钥以后需要在本地配置该密钥对的相关信息,在本地选择信任该密钥
bashgpg --edit-key ABCDEF1234567890
接下来将进入交互模式:
bashtrust
输入 trust 代表对该密钥信任,同时会让你选择信任程度,根据提示选择信任等级,一般选择
5 = I trust ultimately
,然后输入quit
退出。 -
这样就导入成功了,可以使用以下命令来测试,密钥是否导入成功
bashecho "test" | gpg --clearsign
输入密码问题#
在上面的测试过程中,你可能会遇到一个奇怪的不能理解的报错问题:
erasernoob@eraser:~/$ echo "test" | gpg --clearsign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
test
gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device
bash这一一般都是由于 pinentry
可视化界面未安装好或配置错误导致不能弹出弹窗并输入密码。可以选择安装但是没有很大的必要,通过以下步骤可以选择在终端中输入自己的密码:
- 设置
GPG_TTY
echo 'export GPG_TTY=$(tty)' >> ~/.bashrc
source ~/.bashrc
bash再次测试,发现就可以在终端中输入密码了。