使用 GPG 为 Github 签名

编程
4 min read

为什么要用 GPG 为 Commit 签名?

有关 GitHub 上通过修改 git 邮件地址冒充他人的情况,并不少见:

GitHub 的 官方解释 不认为这是 bug:尽管冒充他人身份,并不会获得代码仓库的权限,如果开发者十分介意这个问题的话,可通过 GPG 为提交签名。

数字签名的作用就是证明某个操作确实是由你本人完成的,而非他人伪造,签名后的提交会有一个绿色的 Verified 标记,以下是对配置步骤的记录。

配置步骤

Step 0:配置前,请确保生成可用于签名的秘钥。 注意:GPG 秘钥的用户 ID 电子邮箱必须得有 GitHub 账户 验证过的电子邮箱 ,或者 GitHub 提供的 no-reply 邮箱地址。没有的话,通过 adduid 命令创建。

增加 UID
gpg --edit-key alice@example.com
gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
sec rsa4096/4894D3B52162728F
created: 2022-03-26 expires: 2025-03-25 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/D78845F1E9BF310D
created: 2022-03-26 expires: 2025-03-25 usage: E
[ultimate] (1). alice <alice@example.com>
gpg> adduid
Real name: alice.github
Email address: alice.github@example.com
Comment:
You selected this USER-ID:
"alice.github <alice.github@example.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
sec rsa4096/4894D3B52162728F
created: 2022-03-26 expires: 2025-03-25 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/D78845F1E9BF310D
created: 2022-03-26 expires: 2025-03-25 usage: E
[ultimate] (1) alice <alice@example.com>
[ unknown] (2). alice.github <alice.github@example.com>
gpg> save

设置正确的电子邮箱

git config --global user.email "alice.github@example.com"
# --global 全局配置
# --local 仓库级配置

Step 1:导出用于签名的 PGP 公钥

gpg -a --export [PRIMARYKEYID]

Step 2:在 GitHub 中添加 GPG 公钥。具体步骤参照 这里

Step 3:修改本地 git 配置

git config --global user.signingkey [PRIMARYKEYID]

Step 4:(可选)macOS 如果使用时需要输入密码,请安装 pinentry-mac

brew install pinentry-mac
echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.conf
killall gpg-agent

Step 5:对提交进行签名

git commit -S -m "your commit message"
  1. 当本地分支中的提交更改时,请将 S 标志添加到 git commit 命令;
  2. 输入密码;
  3. 在本地完成创建提交后,将其推送到 GitHub 上的远程仓库 git push
  4. 在 GitHub 对应的代码仓库,检查 commit 信息:Verified(已验证)。

Step 6:对标签进行签名

# 本地签名打tag
git tag -s v1.0.0 -m "my version 1.0.0"
# 验证tag签名
git tag -v v1.0.0
# 推送远程仓库
git push --tag

其他设置和技巧

查看 commit 签名信息

使用 --show-signature 查看 commit 记录和签名信息:

git log --show-signature

配置自动签名

每次提交 commit 信息,手动加参数 -S 过于麻烦,配置自动签名:

git config --global commit.gpgsign true
# --global 全局配置
# --local 仓库级配置

引入 GitHub 公钥

到目前为止,本地的 commit 签名提交没有任何问题,但是 GitHub 网页端的操作:比如新建仓库,或者网页端提交 commit 等,在本地无法验证这些操作的签名,这是因为网页端操作使用的签名为 GitHub 平台自身的签名。为了解决这个问题,按下面配置:

# 引入 github 公钥
curl https://github.com/web-flow.gpg | gpg --import
# 签署 github 公钥
gpg --lsign-key GitHub

引入前:

commit 74d6d8a6***************8b77 (HEAD -> main, origin/main, origin/HEAD)
gpg: 签名建立于 六 3/26 15:33:39 2022 CST
gpg: 使用 RSA 密钥 4AEE18F83AFDEB23
gpg: 无法检查签名:No public key
Author: alice <********+alice@users.noreply.github.com>
Date: Sat Mar 26 15:33:39 2022 +0800
Update README.md
update readme

引入后:

commit 74d6d8a6***************8b77 (HEAD -> main, origin/main, origin/HEAD)
gpg: 签名建立于 六 3/26 15:33:39 2022 CST
gpg: 使用 RSA 密钥 4AEE18F83AFDEB23
gpg: 完好的签名,来自于 “GitHub (web-flow commit signing) <noreply@github.com>[完全]
Author: alice <********+alice@users.noreply.github.com>
Date: Sat Mar 26 15:33:39 2022 +0800
Update README.md
update readme

GPG 公钥导入 GitHub 后,除了为代码提交签名外,也可以作为秘钥分发的一种方式,任何人都可以通过 GitHub 来下载公钥 https://github.com/<帐号名>.gpg

参考资料

本文作者:杨奇的博客
版权声明:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可,非商业转载及引用请注明出处(作者、原文链接),商业转载请联系作者获得授权。
杨奇的博客 微信公众号
微信公众号
杨奇的博客
评论