ChrAlpha's Blog

Thumbnail-%E5%9C%A8%20GitHub%20%E4%B8%8A%E4%BD%BF%E7%94%A8%20GPG%20%E8%AE%A4%E8%AF%81%E4%BD%A0%E7%9A%84%20Git%20Commit

在 GitHub 上使用 GPG 认证你的 Git Commit

2020-03-08·笔记本

由于 Git 的基于邮箱验证身份的特性,你可以十分轻松地伪造成为别人进行 Commit 。那如何保证这个 Commit 真的是开发者提交的呢?这时候就需要一个特殊的密钥——GPG key 进行认证了。

关于 GPG

GNU Privacy Guard(GnuPG 或 GPG)是一个密码学软件,用于加密、签名通信内容及管理 非对称 密码学的密钥。

非对称密码大家应该接触过,这项技术在许多领域都有适用。这种算法需要两个「钥匙」,一个是可以公开的 公钥 ,对应的另一个就是应保管好的 私钥 。用公钥加密的内容只能使用私钥解开,而使用私钥加密的内容也只能使用公钥解开。

目前计算机难以高效地进行质因数分解,比如我们将 2147483647 乘以 998244353 利用计算机很容易得到结果 2143713423777595391 ,但是反过来就扔给你一个 2143713423777595391 很难反推出原来两个质数。

利用这个特性,加上一个合适的流程,我们就得到了一个加密手段。

如果假象我们在使用一个去中心化通讯平台,每个人有唯一的一个账号(公钥)和密码(私钥),我要私聊一个朋友,内容肯定不想让别人知道,但是在去中心化网络中难以避免经过别人转手,这时候我就可以拿那位朋友的账号(公钥)加密,这样只有那位朋友使用自己的私钥才能解开这些内容;同样的,他怎么确定信息是我发出的而不是别人伪造我的身份发出的呢?那我在用他的公钥加密后再使用自己的私钥加密(也叫「签名」),他使用我的公钥发现能解开,那就必是我发出的无疑了。(但是你的私钥泄露了就……)

这次要介绍的 GPG 认证就是使用私钥加密(签名)来完成类似「证明我妈是我妈」这样的操作的。

配置 GPG 签名认证

大概讲了下原理,那么现在就来看看怎么操作。

其实也不复杂,(印象中)所有的 Git 都是带了 GPG 的。如果没有,那就上 这里 寻找合适的版本。安装部分就不再赘述了。

生成密钥

打开终端(Windows 用户则是 Git Bash)

默认生成是使用 gpg --gen-key 生成,但是默认的密钥长度是 2048 bits ,但是 GitHub 要求不低于 4096 bits ,所以改用命令:

gpg --full-generate-key

加密方式直接回车使用默认的 RSA and DSA

接着输入密钥长度,范围在 1024 - 4096 ,应 GitHub 要求请输入 4096

关于密钥过期设置的话,个人使用一般设置为永久,也就是不过期都没关系的。所以我这里默认回车。

之后输入用户信息,按照自己的来填就好了。注意邮箱一定要是在 GitHub 认证过的邮箱,如果该邮箱要保密请使用 GitHub 提供的 no-reply 邮件地址。由于我 GitHub 账号绑定了多个邮箱,分工明确,就直接拿自己专门的邮箱来用了。

然后要设置一个安全密码。至于复杂度自己把握吧,之后同一终端一定时间内 Commit 只需要输入一次密码的。

之后就会将密钥信息打印出在终端了,没有记下来也没关系,后面还可以通过一些命令调出来的。

上传 GitHub

在终端输入:

gpg --list-keys

显示所有本机的密钥。那个长得最奇怪的 40 位 16 进制数便是密钥的 ID 。

接着输入:

gpg --armor --export {key ID}

将指定密钥打印出来。

复制从 -----BEGIN PGP PUBLIC KEY BLOCK----- 开始,到 -----END PGP PUBLIC KEY BLOCK----- 结束这段信息。

这便是你的公钥,GitHub 也是通过它解开你用私钥加密(签名)的 Commit 从而真正认定是你的提交。将这段信息粘贴到「个人 - Settings -SSH and GPG key - New GPG keys」,可能需要你输入 GitHub 账号密码,照做就是了。

如果你在生成密钥的时候没有使用 GitHub 认证过的邮箱的话这里就会提示未经验证。那只能再走一遍上述生成流程,把新密钥的邮箱设为合适的。

终端配置

上述过程全部配置好了,接下来就要让终端知道你使用那个 GPG 签名了。

gpg config user.signingkey {key ID}

如果觉得每个仓库都要这样配置太繁琐,就加上一条 --global 参数。

之后 Commit 的时候加上 -S 表示这次提交需要使用 GPG 加密:

git commit -S -m "commit message"

如果不想每次都手动加上这个 -S ,可以设置为每次 Commit 都默认签名,使用命令:

git config --global commit.gpgsign true

之后正常提交都会要求签名了。

unalted image

至此所有配置都已经完成了,你可以提交试试看。你的 Commit 后面应该已经有 Verified 标识了。

密钥的导入与导出

如果你有多台设备使用需求,使用同一个 GPG key 会免去许多不必要的麻烦。

以文件形式导出

上面导入 GitHub 的时候介绍了可以将公 / 私钥打印到终端里,自然也是可以以文件形式保存下来,方便转移。

在终端中输入命令:

gpg --armor --output GPGtest_pub.gpg --export {key ID}
gpg --armor --output GPGtest-sec.gpg --export-secret-key {key ID}

这样你就在终端的启动路径下得到了两个 GPG 文件,请妥善保管。

从 GPG 文件中导入

如果你手头上有 GPG 文件,导入也颇为简单。终端中输入:

gpg --import GPGtest_pub.gpg
gpg --allow-secret-key-import --import GPGtest-sec.gpg

注意将文件名和路径改为自己的。

信任 GitHub 密钥

其实当你完成上面步骤后已经能十分灵活地使用 GPG 了。但是一些在网页端的操作是由 GitHub 代之签名的,这些操作我们还是无法确定其真实性。

这时候我们需要上传并信任 GitHub 密钥。

curl https://github.com/web-flow.gpg | gpg --import

然后当然是选择相信他~(用自己的签名为其验证)

gpg --sign-key {key ID}

这样你在网页端进行的操作也都是经过验证的了。(但是你的 GitHub 账号密码泄露了就……)

unalted image

可爱的 Verified 认证标记

一番操作后,你的 Commit 终于得到了 Verified 标记,他人想伪造你也变得不再那么可信了。但是 GPG 能做到的远不止如此,还有许多功能值得我们去学习、去深究。

在 GitHub 上使用 GPG 认证你的 Git Commit
本文作者
ChrAlpha
发布日期
2020-03-08
更新日期
2020-03-10
转载或引用本文时请遵守 CC BY-NC-SA 4.0 许可协议,注明出处、不得用于商业用途!
CC BY-NC-SA 4.0