大概是全网第一个 Linux 使用 S/MIME(即X.509)签名 Git 提交的教程

很多人都知道 Git 可以使用 S/MIME 签名,但是很少有人尝试 S/MIME,而是选择 OpenPGP 签名,所以我在这里写一个 S/MIME 的教程,想玩的可以来参考下


先说一句,本文章仅针对 Linux

你应该在点进这篇文章之前已经看过一些其他文档了,如果没有也没关系

关于 S/MIME 你可能找不到其他有用的文档,就连 GitHub 的官方文档也是依托答辩

首先,GitHub 给的这个 github/smimesign 连 Linux 都不兼容,上次提交还是在 2021,底下的教程还是错的

然后,这个 TerminalTerminalGit Bash 是啥玩意?

中文文档更是惨不忍睹

签名提交

我们使用的工具是 gpgsm,在 Debian GNU/Linux 上使用包管理器安装它:

1
apt install gpgsm

如果你使用 Arch Linux,它已经被包含到 gnupg,所以您不需要手动安装它

接下来,简单地执行:

1
gpgsm --import /path/to/secret.pem

然后依次输入你的私钥锁码,为 gpgsm 设置的新密码重复上一步的密码,即可将私钥导入 gpgsm

1
2
3
4
5
6
7
8
9
10
11
12
13
gpgsm: 1224 bytes of 3DES encrypted text
gpgsm: 5288 bytes of RC2 encrypted text
gpgsm: processing certBag
gpgsm: dirmngr cache-only key lookup failed: Not found
gpgsm: processing certBag
gpgsm: processing certBag
gpgsm: DBG: keygrip= AE 02 E3 4B E9 7E 61 0C C3 33 93 67 AF 6A 3D 29 18 B3 68 9B
gpgsm: total number processed: 4
gpgsm: imported: 1
gpgsm: unchanged: 2
gpgsm: secret keys read: 1
gpgsm: secret keys imported: 1

导入完成后,配置 git 使用 gpgsm 进行签名:

1
git config --global gpg.format x509

(是的,git 默认的 X.509 签名工具就是 gpgsm
接下来查看你私钥的 ID:

1
gpgsm --list-secret-keys
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/home/mbrjun/.gnupg/pubring.kbx
-------------------------------
ID: 0xC7D9F286 <<- ID Here!
S/N: 3D7BA6B1C470C8938BBB4B08FEC7A956
(dec): 81724941220654032059336759622481979734
Issuer: /CN=Actalis Client Authentication CA G3/O=Actalis S.p.A./L=Ponte San Pietro/ST=Bergamo/C=IT
Subject: /CN=mbrjun@foxmail.com
aka: mbrjun@foxmail.com
validity: 2022-10-26 16:28:57 through 2023-10-26 16:28:57
key type: 2048 bit RSA
key usage: digitalSignature keyEncipherment
ext key usage: clientAuth (suggested), emailProtection (suggested)
policies: 1.3.159.1.24.1:N:
fingerprint: 6A:B8:DE:4C:82:76:21:E8:4C:F8:6E:BC:DE:61:B3:8F:C7:D9:F2:86
sha2 fpr: FE:C5:8C:B9:B2:0D:B8:DD:36:BE:41:74:5F:B3:A1:90:68:B7:C9:BE:CD:A2:B9:EF:61:FE:DA:64:80:65:AF:96

然后把这个 ID 告诉git,例如:

1
git config --global user.signingkey 0xC7D9F286

将上方命令的 0xC7D9F286 替换为你的私钥 ID

最后,设置 git 的默认签名

1
git config --global commit.gpgsign true

大功告成!立刻使用你的 X.509 证书来签名提交吧!

验证提交签名

git 命令行

打开 git log:

1
git log --show-signature

可以看到 gpgsm 会验证签名证书的有效性:

1
2
3
4
5
6
7
8
9
10
11
commit ab7cb75fb8f3a1193a3297764d56b5231d46a6ee
gpgsm: Signature made 2022-11-13 04:44:10 UTC
gpgsm: using rsa2048 key 6AB8DE4C827621E84CF86EBCDE61B38FC7D9F286
gpgsm: Note: non-critical certificate policy not allowed
gpgsm: Note: non-critical certificate policy not allowed
gpgsm: Good signature from "/CN=mbrjun@foxmail.com"
gpgsm: aka "mbrjun@foxmail.com"
Author: MBRjun <mbrjun@foxmail.com>
Date: Sun Nov 13 12:44:10 2022 +0800

GOOD COMMIT,WITH SMIME SIG(RETRY 1)

github.com

GitHub 验证 X.509 不需要上传公钥,同时也不兼容自签名:

使用 X.509 签名会比其他签名方法多一种状态,即Pending

因为 X.509 还会进行证书吊销检查,证书吊销后,所有使用该证书的签名将会无效