为什么要用 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。