在 macOS 上用 GPG 给 GitHub Commit 签名

GitHub 上带有签名的提交会显示绿色的 Verified 标记。它能证明这次 commit 确实由对应密钥签出,适合在个人项目、开源协作或重要仓库里使用。

这篇记录一下在 macOS 上配置 GPG commit 签名的完整流程。

1. 安装 GPG 和 pinentry-mac

macOS 上推荐用 Homebrew 安装:

brew install gpg pinentry-mac

gpg 负责生成密钥和签名,pinentry-mac 负责弹出密码输入窗口。如果没有配置 pinentry,后面提交时可能会遇到无法输入密码、签名失败等问题。

2. 生成 GPG 密钥

运行:

gpg --full-generate-key

一般按下面这样选择就够用:

密钥类型: RSA and RSA 或默认选项
密钥长度: 4096
有效期: 按需设置;个人长期使用可以选 0,表示不过期
用户名: 自己的名字或常用昵称
邮箱: GitHub 已验证邮箱,或 GitHub 提供的 noreply 邮箱

GitHub 的 noreply 邮箱格式通常类似:

{ID}+{username}@users.noreply.github.com

可以在 GitHub 的 Email 设置里查看。

3. 配置 pinentry-mac

把 pinentry 写入 GPG Agent 配置:

mkdir -p ~/.gnupg
echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

如果 ~/.gnupg 权限不安全,GPG 可能会提示 warning,可以修一下:

chmod 700 ~/.gnupg
chmod 600 ~/.gnupg/* 2>/dev/null || true

4. 查看密钥 ID

运行:

gpg --list-secret-keys --keyid-format LONG

输出大概是这样:

sec   rsa4096/144E56E3F7BA871F 2024-10-14 [SC]
      17FBC8088AA8800F51F665CB144E56E3F7BA871F
uid                 [ultimate] Infsr <name@example.com>
ssb   rsa4096/F4849F30AEA8C3FD 2024-10-14 [E]

这里 rsa4096/ 后面的 144E56E3F7BA871F 就是后面要用的 signing key ID。

5. 导出公钥并添加到 GitHub

导出公钥:

gpg --armor --export 144E56E3F7BA871F

复制从下面这一行开始:

-----BEGIN PGP PUBLIC KEY BLOCK-----

一直到这一行结束:

-----END PGP PUBLIC KEY BLOCK-----

然后打开 GitHub 设置页:

Settings -> SSH and GPG keys -> New GPG key

也可以直接访问:https://github.com/settings/keys

6. 配置 Git 默认使用该密钥签名

设置签名密钥:

git config --global user.signingkey 144E56E3F7BA871F

让 Git 默认给 commit 签名:

git config --global commit.gpgsign true

如果只想在某个仓库启用,把 --global 去掉,在仓库目录里执行即可。

7. 测试签名提交

随便做一次提交:

git commit -S -m "test: signed commit"

如果弹出密码输入框,输入 GPG 密钥密码即可。推送到 GitHub 后,commit 旁边应该会显示绿色的 Verified

常见问题

提交时报 gpg failed to sign the data

优先检查 pinentry 是否配置正确:

gpgconf --kill gpg-agent
gpg --list-secret-keys --keyid-format LONG

然后重新提交。如果仍然失败,确认 git config user.signingkey 填的是密钥 ID,而不是邮箱或完整指纹。

GitHub 没有显示 Verified

通常是这几个原因:

1. 公钥没有添加到 GitHub
2. commit 使用的邮箱不是 GitHub 已验证邮箱
3. 配置的 signing key 不是这次 commit 实际使用的密钥
4. commit 是配置签名之前创建的,旧 commit 不会自动变成 Verified

小结

流程可以概括成四步:

安装 GPG -> 生成密钥 -> 把公钥添加到 GitHub -> 配置 Git 使用该密钥签名

配置完成后,后续 commit 会自动签名。对经常维护的仓库来说,这是一个一次配置、长期受益的小细节。