gpg使用记录
要了解什么是GPG,就要先了解PGP。
1991年,程序员Phil Zimmermann为了避开政府监视,开发了加密软件PGP。这个软件非常好用,迅速流传开来,成了许多程序员的必备工具。但是,它是商业软件,不能自由使用。所以,自由软件基金会决定,开发一个PGP的替代品,取名为GnuPG。这就是GPG的由来。
GPG有许多用途,本文主要介绍文件加密。至于邮件的加密,不同的邮件客户端有不同的设置。
当前我的系统环境是Ubuntu 22.04
gpg版本是gpg (GnuPG) 2.2.27
。
创建密钥对
1 | # 快速生成密钥对 |
这里我们使用 –full-gen-key 来生成密钥对,首先选择密钥类型,选择 1 (默认) 即可
1 | $ gpg --full-gen-key |
然后选择密钥长度,没有特殊需求的话保持 3072 的默认选项即可
1 | RSA keys may be between 1024 and 4096 bits long. |
然后设置密钥的有效期,因为我们需要长期使用,所以选择 0 ,密钥永不过期, 也可以输入2y, 表示2年。
1 | Please specify how long the key should be valid. |
确定后,依次输入姓名、电子邮件和注释 (可以不填),然后选择 o 确定, 确定后会出现一个窗口让输入密码,自行设置一个密码。然后密钥就创建成功了, 通过命令gpg --list-keys
可以查看当前的密钥
这里有一串字符。就是key的id,后面的操作都需要这个。
创建子密钥
上面创建的是公钥,如果使用这个密钥加密, 那么如果密钥不小心泄露, 就必须吊销整个密钥。所以我们创建子密钥来使用。
1 | gpg --edit-key 4208C2FA114EE038F9EAD2374808D00D9D910E74 |
进入gpg控制台, 输入 addkey
输入一些选择, 过期时间建议2y,然后输入密钥的密码后,在控制台输入save保存退出。
导出密钥
导出密钥默认是二进制存储,如果需要纯文本,加上 --armor
参数
导出主密钥
1 | gpg -o /data/gpg_key --export-secret-keys 4208C2FA114EE038F9EAD2374808D00D9D910E74 |
主密钥一定要保存好,不要泄露
导出子密钥
1 | gpg -o /data/gpg_key.sub --export-secret-subkeys 4208C2FA114EE038F9EAD2374808D00D9D910E74 |
导出公钥
公钥是需要公开的,可以将公钥发送给别人,别人用于加密
1 | gpg --armor --output /data/public-key.txt --export 4208C2FA114EE038F9EAD2374808D00D9D910E74 |
上传公钥
也可以将公钥上传到公共服务器上
1 | gpg --send-keys 4208C2FA114EE038F9EAD2374808D00D9D910E74 |
导出吊销证书
1 | gpg --generate-revocation 4208C2FA114EE038F9EAD2374808D00D9D910E74 |
不过实际上在生成密匙时就已经生成了一份吊销证书了,放在这个目录下面 ~/.gnupg/openpgp-revocs.d/
1 | mv ~/.gnupg/openpgp-revocs.d/4208C2FA114EE038F9EAD2374808D00D9D910E74.rev /data/ |
卸载密钥
1 | gpg --delete-secret-keys 4208C2FA114EE038F9EAD2374808D00D9D910E74 |
使用密钥
导入密钥
在自己的 电脑上面
1 | gpg --import /data/gpg_key.sub |
加密
1 | gpg --recipient 4208C2FA114EE038F9EAD2374808D00D9D910E74 --output test_en.txt --encrypt test.txt |
解密
1 | gpg test_en.txt |
签名
有时,我们不需要加密文件,只需要对文件签名,表示这个文件确实是我本人发出的。sign参数用来签名。
1 | gpg --sign test.txt |
然后生成了一个test.txt.gpg文件,我们打开这个文件后,发现这也是一个二进制的数据,这并不是加密后的数据,与上边的二进制数据不一样。如果想生成ASCII码的签名文件,可以使用clearsign参数
1 | gpg --clearsign test.txt |
如果想生成单独的签名文件,与文件内容分开存放,可以使用detach-sign参数。
1 | gpg --detach-sign test.txt |
是一个二进制的数据,如果想采用ASCII码形式,要加上armor参数
1 | gpg --armor --detach-sign test.txt |
签名+加密
1 | gpg --local-user [发信者ID] --recipient [接收者ID] --armor --sign --encrypt test.txt |
local-user参数指定用发信者的私钥签名,recipient参数指定用接收者的公钥加密,armor参数表示采用ASCII码形式显示,sign参数表示需要签名,encrypt参数表示指定源文件。
验证签名
我们收到别人签名后的文件,需要用对方的公钥验证签名是否为真。verify参数用来验证
1 | gpg --verify test.txt.asc test.txt |
配合GitHub使用
首先,需要让Git知道签名所用的GPG密钥ID
1 | git config --global user.signingkey {key_id} |
然后,在每次commit的时候,加上-S参数,表示这次提交需要用GPG密钥进行签名:
1 | git commit -S -m "..." |
如果觉得每次都需要手动加上-S有些麻烦,可以设置Git为每次commit自动要求签名:
1 | git config --global commit.gpgsign true |
然后添加变量到.bashrc
1 | export GPG_TTY=$(tty) |
commit时皆会弹出对话框,需要输入该密钥的密码,以确保是密钥拥有者本人操作