配置
名字和邮箱
在命令行输入:
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
因为 Git 是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和邮箱。大多数情况下,Git 就是靠这些来确定身份的。
注意 git config
命令的 --global
参数,这表示将配置设置为全局的。全局设置对本机的每个仓库都生效。
SSH 密钥
SSH 密钥用于连接 GitHub 或者类似的托管服务。
首先查看你的 SSH 密钥是否已经生成。
ls ~/.ssh
如果你没有生成过 SSH 密钥,那么这个目录应该是不存在的。你可以使用 ssh-keygen
命令来生成一个新的密钥。
ssh-keygen -t ed25519
如果在 Windows 系统上找不到 ssh-keygen
命令,那么可以在 Git Bash 中运行。
生成完成后,查看生成的公钥:
cat ~/.ssh/id_ed25519.pub
在 GitHub 上添加这个公钥,然后检测一下是否成功:
$ ssh -T [email protected]
Hi Wybxc! You've successfully authenticated, but GitHub does not provide shell access.
看到这样的欢迎信息,说明 SSH 密钥添加成功。
GPG 密钥
上面提到 Git 在确定身份的时候用的是名字和邮箱,但是,这也意味着只要知道了别人的名字和邮箱,就可以冒充他的身份。理论上,这种冒充是无法甄别的,甚至 GitHub 也无法避免。
所以,在名字和邮箱以外,Git 还有另一重保护措施:GPG 密钥。你可以使用自己的 GPG 私钥对提交进行签名,这样别人就能通过公钥鉴定身份。如果你的所有提交都经过签名,那么别人就知道没有签名的那些提交就是冒牌货。
在 Git 2.34 之后,可以用 SSH 密钥代替 GPG 密钥进行签名。这样不仅统一了身份验证方式,还免去了每次提交时都要输入 GPG 密码的麻烦。希望使用 SSH 密钥的可以跳过本节。
生成 GPG 密钥:
gpg --full-generate-key
如果在 Windows 系统上提示找不到 gpg 命令,可以在 Git Bash 中运行。
基本按照默认配置即可。生成时需要填写名字和邮箱,需要和 Git 的配置一致,而且邮箱需要和 GitHub 账号认证的邮箱一致。
如果生成的是 RSA 密钥,需要设置密钥长度。GitHub 要求 RSA 密钥是 4096 位。
生成过程中会给密钥设置密码,这个密码是解锁私钥的关键。
生成完成后,查看生成的密钥:
$ gpg --list-secret-keys --keyid-format LONG
~/.gnupg/pubring.kbx
-----------------------------------------------
sec ed25519/85E18D73E1B2E193 2022-06-15 [SC]
6BBEA37A752DBC75008ABB6B85E18D73E1B2E193
uid [ultimate] 忘忧北萱草 <[email protected]>
ssb cv25519/FB6CDE598D2CD679 2022-06-15 [E]
这里的 85E18D73E1B2E193
就是密钥 ID。
将 GPG 与 git 相关联:
git config --global user.signingkey 85E18D73E1B2E193
git config --global commit.gpgsign true
此时可以随便开一个 Git 仓库,测试一下 GPG 签名是否可用:
$ git init test
$ cd test
$ echo "test" > test.txt
$ git add .
$ git commit -m "test"
$ git cat-file commit HEAD
tree 02bdfa7bef60afbeb20ae09bb3145e2a4b1cb977
author 忘忧北萱草 <[email protected]> 1655478113 +0800
committer 忘忧北萱草 <[email protected]> 1655478113 +0800
gpgsig -----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEpRDvWeHZl2iUnVm+/Xek1OdFr8MFAmKsl2EACgkQ/Xek1OdF
r8PWLQ/+JO2J99tFrMqK4eFPbhhDVbQJBxmYcJHS/iSVqxm6c8S97itQ//7QnLIe
rpk1/jspbLm4E5f4EzYeoX4v9UstSDBpgrYnAQj81txwZ8l4Kps/XGv4lXDaaTrH
E8V3Bk3zRj57RjLQwRC2TZGFZXJy6/bQUjgMS3jkiGdcpUsBzrVXmo5sOmPtM8GN
m1yB1mgy/jjs8nuJIKG8hf1NuAaG+ST8hToEGDb5rYdBCLc4R8dPkp4Ha+3SHcZy
MMBvAf5STWQAW7gq6Vwsdqj9IqF4DQga5yWvodnJkKtbkJY5RIvgh1NLrT4/M266
KnVbRgd6ifPzUJb4yyhuOUR32y52JqYXz3SGb7HMkN541HtquaClSCt45lsTACzO
2AhrtlMl3GYCL9EedQ8ql9cCn+Aj2Ol/PnizK49dE+Vfc/KtzUU+9vsMOD1aZ2vW
2M8Nz5GLiLX7lpnOUviYnMf7/VStTbeielvcKnC4FQDbJK86yEmjjK+tCTgoiGo3
Eive7LPB0H9ruenXx26hlOwP1vb2PUSWxXXM0bwEjktrvCRX8byE4w/q9gN8G8TZ
kZJbvyPh5JBDnq1AIhhyPu9nnizmFml10ynWxqwPQplVG4g1SkV2kYTd8rvt2Jit
Dj/ka9f1Sh6T2r5r06WNA+DvRJrbYWDovOU68Edj7XALTfmZNeM=
=pF8U
-----END PGP SIGNATURE-----
能够在 commit 中看到 GPG 签名,说明 GPG 签名已经在 Git 中配置成功。
如果配置 GPG 之后,提交时 Git 找不到 GPG,那么可以手动设置一下 GPG 的路径:
$ which gpg
/usr/bin/gpg
$ git config --global gpg.program /usr/bin/gpg
如果遇到 error: gpg failed to sign the data
的问题,可以尝试把 GPG_TTY
环境变量设置为 $(tty)
(参考):
$ git config user.signingKey 38AF394C
$ git config commit.gpgSign true
$ echo "test" | gpg --clearsign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
test
gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device
$ export GPG_TTY=$(tty)
$ echo "test" | gpg --clearsign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
test
-----BEGIN PGP SIGNATURE-----
XXXXXX SUCCESS XXXX
-----END PGP SIGNATURE-----
ref: https://github.com/keybase/keybase-issues/issues/2798
接下来导出 GPG 公钥,然后添加到 GitHub 中:
$ gpg --armor --export 85E18D73E1B2E193
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEYqn6LBYJKwYBBAHaRw8BAQdAdUKrYViGQwyP6OvG0zi4BtkztQSHmVSzJweG
RH5YbkC0HuW/mOW/p+WMl+iQseiNiSA8d3lieGNAcXEuY29tPoiTBBMWCgA7FiEE
a76jenUtvHUAirtrheGNc+Gy4ZMFAmKp+iwCGwMFCwkIBwICIgIGFQoJCAsCBBYC
AwECHgcCF4AACgkQheGNc+Gy4ZMLvgD+LPHZ/61I3V2QtcQxjhE7Mmx/zzf7nMu9
yoKsBS0DoHsBAOmGcnz8Ldxt8g5annPoS4JXhyC0vUgvBl5ks+LQ6WILuDgEYqn6
LBIKKwYBBAGXVQEFAQEHQKwoXBZT20+8mEfaqAuSEyMi4eeiE1Adjkj0TCZuV2UE
AwEIB4h4BBgWCgAgFiEEa76jenUtvHUAirtrheGNc+Gy4ZMFAmKp+iwCGwwACgkQ
heGNc+Gy4ZOtkwEAuyAAI2Va4xNuXwWf+WZg7Bt5KcXfcezYGG3EDFstaJMA/i6O
B1wiq7kByLBFmRVBGewKpDA2Z2UGnAQuSvCY5nwF
=FzfD
-----END PGP PUBLIC KEY BLOCK-----
之后,提交的 commit 在 GitHub 上就会显示 verified
,表明这条 commit 是通过了 GPG 签名认证的。
使用 SSH 密钥签名
新版本的 Git(2.34 及以上)支持使用 SSH 密钥进行签名。这样就不需要单独生成 GPG 密钥了,可以直接用身份验证的同一个 SSH 密钥进行签名。
设置使用 SSH 代替 GPG 签名:
git config --global gpg.format ssh
git config --global commit.gpgsign true
指定签名用的密钥文件:
git config --global user.signingKey ~/.ssh/id_ed25519.pub
然后,需要创建一个文件,向 Git 告知允许用于签名的公钥列表:
echo "namespaces=\"git\" $(cat ~/.ssh/id_ed25519.pub)" >> ~/.ssh/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
然后就可以尝试对提交进行签名了:
$ git commit -m "test"
$ git cat-file commit HEAD
tree 4fb2d17608d9c85a6d969958025aabc42c3675ab
parent c6ca279780537f71a27da03325e5184fc344d529
author 忘忧北萱草 <[email protected]> 1744253548 +0800
committer 忘忧北萱草 <[email protected]> 1745379033 +0800
gpgsig -----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgqar+eQdcNA/Pn7FaQGDKsynneJ
CqhBR4StF0mRGJgr4AAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
AAAAQCNDJfrIOVYx2UUnFfdhPAjKhYx4m5xTcR27JqRgu+KKJDXFPQltvqRAR/HrbLbPwT
JrKbTvas1MKINpOXr0rA0=
-----END SSH SIGNATURE-----
可以看到,gpgsig
中的内容是 SSH 签名。
之后,在 GitHub 上将 SSH 公钥添加为签名密钥(即使是与验证密钥相同的密钥,也要再添加一次,因为是不同的用途),然后就可以在 GitHub 上看到 verified
的标记了。