前阵子重读了一篇旧文A Git Horror Story: Repository Integrity With Signed Commits,感觉还是有必要通过GPG签名来提交的来源可信。于是抽空重新配置了本地的开发环境,把GPG-sign补上了。
准备工作
在 Keybase 注册账号。
使用Keybase的原因是可以在网站上托管密钥(加密过),方便迁移。
工具安装(HomeBrew)
1
2
| $ brew install gnupg
$ brew cask install gpg-suite keybase
|
环境配置
使用keybase创建GPG密钥
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| $ keybase pgp gen --multi
Enter your real name, which will be publicly visible in your new key: Josta Yee
Enter a public email address for your key: [email protected]
Enter another email address (or <enter> when done):
Push an encrypted copy of your new secret key to the Keybase.io server? [Y/n] Y
When exporting to the GnuPG keychain, encrypt private keys with a passphrase? [Y/n] Y
▶ INFO PGP User ID: Josta Yee <[email protected]> [primary]
▶ INFO Generating primary key (4096 bits)
▶ INFO Generating encryption subkey (4096 bits)
▶ INFO Generated new PGP key:
▶ INFO user: Josta Yee <[email protected]>
▶ INFO 4096-bit RSA key, ID 438BDA794F609085, created 2018-08-18
▶ INFO Exported new key to the local GPG keychain
|
填入想要签名的user.name/user.email,一路回车确认完成。
修改Git配置文件
1
2
3
4
5
6
7
8
| $ gpg --list-secret-keys --keyid-format LONG
/Users/yee/.gnupg/pubring.kbx
-----------------------------
sec rsa4096/438B********9085 2018-08-18 [SC] [expires: 2034-08-14]
64D89F4FE50C****************DA794F609085
uid [ unknown] Josta Yee <[email protected]>
ssb rsa4096/2E16********79D7 2018-08-18 [E] [expires: 2034-08-14]
|
把输出的sec rsa4096/
后面一段加入~/.gitconfig
1
2
3
| $ git config --global user.signingkey 438B********9085
$ git config --global commit.gpgsign true
$ git config --global gpg.program $(which gpg)
|
顺便添加gnupg的配置文件:
1
2
| $ echo "use-agent\nno-emit-version\ndefault-key 438B********9085" > ~/.gnupg/gpg.conf
$ echo "use-standard-socket\ndefault-cache-ttl 600\nmax-cache-ttl 7200" > ~/.gnupg/gpg-agent.conf
|
接着将生成的key公钥导入平台
1
2
3
4
5
6
| $ keybase pgp list
Keybase Key ID: 010198df77b67748078160a4************************90b658de038d24d98d680a
PGP Fingerprint: 64D8 9F4F E50C **** **** **** **** DA79 4F60 9085
PGP Identities:
Josta Yee <[email protected]>
|
- 导出公钥(使用Keybase key ID的前16位字符即可)
1
| $ keybase pgp export -q 010198df77b67748 | pbcopy
|
为了能让tty操作时正确弹窗提示输入密码,还需要在shell配置里面设置GPG_TTY
环境变量:
这样在git commit
时会看到:
1
2
3
4
5
6
7
8
9
| │ Please enter the passphrase to unlock the OpenPGP secret key: │
│ "Josta Yee <[email protected]>" │
│ 4096-bit RSA key, ID EF9AAFDEF0AA499C, │
│ created 2018-08-13. │
│ │
│ │
│ Passphrase: __________________________________________________ │
│ │
│ <OK> <Cancel> │
|
输入密码验证通过后就成功了:
1
2
| [master 90e1fce] ok
1 file changed, 1 insertion(+)
|
密码会缓存一段时间,不用每次都重复输入。
然后测试一下push,最后就能在网页上看到被认证的绿色Verified提示了。
多账号支持
工作开发使用的公司账号,现在是通过使用Git config includeIf区分,这里同样可以针对不用用户签名,只需新生成一套密钥,在gitconfig-work
加入即可,如下:
新设备导入
添加新设备时导入之前生成的密钥非常简单,登录keybase账号之后将需要的公私钥分别导入至本地PGP keychain即可:
1
2
3
4
5
6
| $ keybase pgp export -q 010198df77b67748 | gpg --import
$ keybase pgp export -s -q 010198df77b67748078160a4************************90b658de038d24d98d680a | gpg --import --allow-secret-key-import
# 检查导入结果
$ gpg --list-keys
$ gpg --list-secret-keys
|
注意从keybase导出私钥时keyID不可以使用前16位简写,否则可能报 ERROR No matching keys found
错误而失败。
备注
- Git之父Linus Torvalds本人并不赞成signed commits,具体可以参见当年的邮件列表。
- GitHub只识别第一个登记邮箱,所以在生成时不要填写多个email比较好。
- 如果提交失败,可以使用
echo "test" | gpg --clearsign
检查是否能正确签名,还可以设置GIT_TRACE=1
打开Git操作的跟踪日志作调试。
参考
History
Version | Action | Time |
---|
1.0 | Initial commit | Aug 18, 2018 |
1.1 | How to import keys after adding a new device | Dec 25, 2018 |