为什么要用 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" |
- 当本地分支中的提交更改时,请将 S 标志添加到 git commit 命令;
- 输入密码;
- 在本地完成创建提交后,将其推送到 GitHub 上的远程仓库
git push
; - 在 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
。