使用GPG对Git commit/tag进行签名

演示环境

  • 系统:MacOS、Ubuntu
  • Git版本:2.40.0
  • IDE:Goland 2023.3.3

为什么要签名

GPG 可以对 Git commit 或 tag 进行签名,其它用户可以知道这个commit来源可信,也就是作者本人提交的代码。

MacOS系统

到 GPG Tools 官网( https://gpgtools.org/ )下载并安装 GPG Suite 工具,安装过程比较简单就不再赘述了。

然后执行 gpgconf应该会得到类似如下的配置信息。

1
2
3
4
5
6
gpg:OpenPGP:/usr/local/MacGPG2/bin/gpg
gpgsm:S/MIME:/usr/local/MacGPG2/bin/gpgsm
gpg-agent:私钥:/usr/local/MacGPG2/bin/gpg-agent
scdaemon:智能卡:/usr/local/MacGPG2/libexec/scdaemon
dirmngr:网络:/usr/local/MacGPG2/bin/dirmngr
pinentry:密码条目:/usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac

Ubuntu系统

执行如下命令安装相关命令行软件。
sudo apt -y install gnupg2 gnupg-agent pinentry-gnome3

然后执行 gpgconf应该会得到类似如下的配置信息。

1
2
3
4
5
6
gpg:OpenPGP:/usr/bin/gpg
gpg-agent:私钥:/usr/bin/gpg-agent
scdaemon:智能卡:/usr/lib/gnupg/scdaemon
gpgsm:S/MIME:/usr/bin/gpgsm
dirmngr:网络:/usr/bin/dirmngr
pinentry:密码条目:/usr/bin/pinentry

生成 GPG Key

可以使用 GPG Keychain ( MacOS ) 或 CLI 命令生成 GPG Key ,根据自己的喜好选择其中一种生成方式。

使用 GPG Keychain 生成 Key

  1. 打开安装好的 GPG Keychain 工具,在主界面点击创建按钮,然后填写信息,点击 Create Key 确认创建。这里用于演示,密码设置的比较简单,实际使用的时候不建议使用弱密码。

生成 GPG Key

  1. 完成创建后可在 GPG Keychain 主界面的列表中看到刚刚创建的Key。

生成后的 GPG Key 列表

使用 CLI 生成 Key

  1. 打开终端,执行命令 gpg --full-generate-key ,然后按引导完成信息填写。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
gpg (GnuPG/MacGPG2) 2.2.41; Copyright (C) 2022 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

请选择您要使用的密钥类型:
   (1) RSA 和 RSA (默认)
   (2) DSA 和 Elgamal
   (3) DSA(仅用于签名)
   (4) RSA(仅用于签名)
 (14)卡中现有密钥
您的选择是?
RSA 密钥的长度应在 1024 位与 4096 位之间。
您想要使用的密钥长度?(3072)
请求的密钥长度是 3072请设定这个密钥的有效期限。
         0 = 密钥永不过期
      <n>  = 密钥在 n 天后过期
      <n>w = 密钥在 n 周后过期
      <n>m = 密钥在 n 月后过期
      <n>y = 密钥在 n 年后过期
密钥的有效期限是?(0)
密钥永远不会过期
这些内容正确吗? (y/N) y

GnuPG 需要构建用户标识以辨认您的密钥。

真实姓名: mingming.wang
电子邮件地址: contact@mingming.wang
注释:
您选定了此用户标识:
    “mingming.wang <contact@mingming.wang>”

更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)? o
我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘
、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数
发生器有更好的机会获得足够的熵。
我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘
、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数
发生器有更好的机会获得足够的熵。
gpg: 吊销证书已被存储为‘/Users/user/.gnupg/openpgp-revocs.d/D913D0FA1E6CBCE92E2778A3956777BF98727EF3.rev’
公钥和私钥已经生成并被签名。

pub   rsa3072 2023-05-10 [SC]
      D913D0FA1E6CBCE92E2778A3956777BF98727EF3
uid                      mingming.wang <contact@mingming.wang>
sub   rsa3072 2023-05-10 [E]
  1. 执行 gpg --list-keys --keyid-format=long 查看刚刚创建的Key是否在列表中。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/Users/ming/.gnupg/pubring.kbx
------------------------------
pub   dsa2048/76D78F0500D026C4 2010-08-19 [SC] [有效至:2024-05-11]
      85E38F69046B44C1EC9FB07B76D78F0500D026C4
uid                   [ 未知 ] GPGTools Team <team@gpgtools.org>
uid                   [ 未知 ] [jpeg image of size 6329]
sub   rsa4096/E8A664480D9E43F5 2014-04-08 [S] [有效至:2024-05-11]
sub   rsa4096/E73107F9EF97597C 2020-05-11 [E] [有效至:2024-05-11]

pub   rsa4096/8A9E3745558E41AF 2020-05-04 [SC] [有效至:2024-05-03]
      B97E9964ACAD1907970D37CC8A9E3745558E41AF
uid                   [ 未知 ] GPGTools Support <support@gpgtools.org>
sub   rsa4096/B35D2E404496652B 2020-05-04 [E] [有效至:2024-05-03]

pub   rsa3072/956777BF98727EF3 2023-05-10 [SC]
      D913D0FA1E6CBCE92E2778A3956777BF98727EF3
uid                   [ 绝对 ] mingming.wang <contact@mingming.wang>
sub   rsa3072/1F969992B93D1EA3 2023-05-10 [E]

为GitHub 账号配置 GPG Key

  1. 执行 gpg --armor --export 956777BF98727EF3 查询 GPG Public Key信息,复制所有Public Key 的内容,包含 -----BEGIN PGP PUBLIC KEY BLOCK----------END PGP PUBLIC KEY BLOCK-----
1
2
3
4
5
6
7
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQGNBGRbT0YBDADJLoFcxkpKqQKLoi6/Xx32sWj5Hl9+BbL2UhS+7YeVaG+dbRo8
... 中间部分省略 ...
esmBsc0uYInNCxM+qLT3uXc=
=LJum
-----END PGP PUBLIC KEY BLOCK-----
  1. 进入 Github 的 GPG 设置页面,Settings / SSH and GPG Keys ,点击 New GPG Key 按钮。
  2. 填写第一步获取的 GPG Public Key 信息,并点击 Add GPG Key 按钮

签名 Commit

设置Git

这里设置的 /usr/local/MacGPG2/bin/gpg 来源于上一步骤中,通过执行 gpgconf 可以查询到。
如果只针对单个项目配置GPG签名,可以把下面命令中的 --global 参数去掉。

1
2
3
4
git config --global gpg.program /usr/local/MacGPG2/bin/gpg
git config --global --unset gpg.format
git config --global commit.gpgsign true
git config --global user.signingkey 956777BF98727EF3

CLI环境下签名

在进行 git commit 时,添加 -S 参数,表示这个commit使用签名。-S 后可以指定 <keyid> 来使用不同的 GPG Key,如果未指定则使用默认的 Key Id 。

1
2
git add .
git commit -S -m "Initial commit"

Goland环境下签名

在 Goland 设置页面选择 Git Commit 所使用的 GPG Key,Settings / Version Control / Git / Commit / Configure GPG Key,然后正常进行 Git Commit 会自动进行签名。

Goland 配置

在 Github 页面验证效果

Github Commit

备份与导入

为了在其它电脑或在重装系统后依然能使用之前的 GPG Key,你需要把生成的 GPG Key 进行备份,然后存储到一个安全的介质中(如:U盘、密码管理软件等),在需要的时候导入 GPG Key。

UI界面操作

使用界面操作比较简单,只需要在 GPG Keychain 主界面,点击导入导出按钮按引导操作即可。

CLI备份

  1. 导出私钥,私钥包含公钥信息,所以如果备份了私钥,公钥就不需要导出备份了。
1
gpg --export-secret-keys --armor 956777BF98727EF3 > gpg_private.key
  1. 导出公钥
1
gpg --export --armor 956777BF98727EF3 > gpg_public.key

CLI导入

1
gpg --import gpg_private.key

参考资料