杂笔:GPG key在Github上的使用

2,243 阅读3分钟

在 Github 上创建一个仓库并初始化 README 后,可以看到提交记录里已经有了第一次 Initial commit,而这个 commit 有个小绿框 Verified,OK,看到这个那么你可以确保这是 Github 的提交。

verified-commit

好了,我们现在可以来探讨人生了~呸!程序员之间探讨的应该是核心技术。

关于 Git 签名

Git 从某种意义上来说是加密的,因为你根本看不懂它存储的 .git/objects 是什么东西。但是也有可能不安全,当一些 commits/tags 都有着相同的用户名时,其中某一个或许是 faker。

同事 B 把他的 git config user.name 设置成同事 A 的,查看 commits 时看到的都是同事 A 的提交。最后同事 B 删库跑路了,同事 A 背锅,凉凉~

相信大家都是好同事,不会跑路时写个线上 bug 让别人背锅 😁

Git 提供一种签名方式,你可以给 tag/commit 打上自己的 GPG 签名,这样就能防止假冒了,除非你电脑被偷了。

标签签名

一般打的是附注标签,带信息的那种:

$ git tag --sign v1.0 -m '签名了'
$ git show v1.0
# 会看到这样的一段签名文本
-----BEGIN PGP SIGNATURE-----
iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut
LQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b
RUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=
=EFTF
-----END PGP SIGNATURE-----

验证此签名很简单:

$ git tag --verify v1.0
gpg: Signature made Mon Jun  1 13:37:22 2020
gpg:                using RSA key
gpg: Good signature from "xxx" [ultimate]

你自己打得签名验证没问题,关键是别人的,但还需要别人签名的 public key,这个稍候介绍。

提交签名

生成 GPG key 的时候会提示输入密码,签名的时候也需要:

$ git commit --gpg-sign=KEYID -m '签名了'
You need a passphrase to unlock the secret key for...

全局配置 keyid 就不用每次都复制了:git config --global user.signingkey=xxx

验证也很简单:

$ git show --show-signature 4836fbc

合代码的时候还可以指明分支上的每一个 commit 都需要签名,不过这需要每个人每次提交时都签名,,,有点难,还需要大家学习相关知识,那算了~反正都是面对面提交。

看上面这么多的代码敲了也没用,因为你们还没有 GPG key 😏

简单了解下 GPG

GUN Privacy Guard,简称 GPG,是一个开源加密工具,更广泛的用途是签名。前身是 PGP,一个程序员开发用来加密邮件用的,但它是个商业软件,需要收费,卒。

听说(维基),使用的是混合加密方式,对称加密提高速度,但它又有非对称中的公钥给别人。加密的时候用公钥对,给数据加上一个 digital signature(数字签名),解密后就能验证是谁的了。

原理不是我这等菜鸡程序员才能掌控的,光是了解就花了 2-3 天时间,so 看看咋用。

一般来说要先生成个 GPG key。Windows 用户没有现成的,装 Git 后就有了,打开 git-bash.exe 即可。

$ gpg --generate-key
# 接下来就是按照提示操作
# 输入姓名、注释、密码等等

如果忘了,查看自己的 GPG key:

$ gpg --list-keys
/c/Users/xxx/.gnupg/pubring.kbx
-------------------------------
pub   rsa2048 2020-05-07 [SC]
      950A9EE90899D390E7170F3677F4EA989007A81A
uid           [ultimate] xxx <email>
sub   rsa2048 2020-05-07 [E] [expires: 2022-05-07]

记得之前 commit 需要的 keyid 吗?可以这样获取:

$ gpg --list-secret-keys --keyid-format LONG
/Users/hubot/.gnupg/secring.gpg
------------------------------------
sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
uid                          Hubot
ssb   4096R/42B317FD4BA89E7A 2016-03-10

里面的 3AA5C34371567BD2 就是 GPG key ID。

其它的命令诸如加解密、编辑、与 keyserver 之间的互动等,可以通过 gpg --help 了解。

Github 上的使用

英雄用武之地,在 Github 上显示小绿框 Verified,一看就给人安全的感觉!

上传你的 GPG key 到 Github 上,也就是在你配 SSH 的地方。注意配置邮箱,Github 上的信息关联都是基于邮箱的,包括 commit 等等。

导出自己的 public key:

$ gpg --armor --export 3AA5C34371567BD2
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFmUaEEBCACzXTDt6ZnyaVtueZASBzgnAmK13q9Urgch+sKYeIhdymjuMQta
7/ey2OzRYJmuyK184nc/jIhpLnLi+wC3N5rU21N+ertH/ueUyacn97bHUR4fG9O8
iua0KLZzwAWXBMAO5MpcGuhB17yKCRnnombCCMxNQIKVkdsn/yxRUv9MKQqYXFDW
4cU==Hb2l
-----END PGP PUBLIC KEY BLOCK-----

复制粘贴完成后,提交一次带签名的,会发现多出来个小绿框,大功告成。可是 Github 是怎么验证的呢?翻了遍 gpg 的命令,仍然木有头绪。

so 先学习下怎么在本地验证 Github 仓库里的第一次 Initial commit

$ git show --show-signature df4cc2f
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT
gpg: Can't check signature: public key not found
error: could not verify

显然验证失败了,没有 public key。好在 Github 的直接公开了,可以直接下载:github.com/web-flow.gp…。看了其内容发现和自己之前上传的差不多。

接下来导入这个 key 就行了:

$ gpg --import web-flow.gpg
$ gpg --list-keys
# 看到多了个 key,来自于 Github

再次验证 Github 的那次 commit,发现验证成功,Good!

$ git show --show-signature df4cc2f
commit df4cc2f1a7680549e667a7c5f4dc62c7a2b509a2
gpg: Signature made Fri Apr  3 22:15:36 2020
gpg:                using RSA key 4AEE18F83AFDEB23
gpg: Good signature from "GitHub (web-flow commit signing) <noreply@github.com>" [full]

想必 Github 的验证小绿框也如是了。。。

参考链接