本文最后更新于 2024 年 4 月 19 日
本文以 Ubuntu 22.04 为例,介绍如何使用 GPG( GNU Privacy Guard )软件进行密钥的管理,以及 GPG 的基本使用方法及日常使用建议。
了解
请先了解,什么是 PGP、OpenPGP、GPG 。
以下是有用的链接:
OpenPGP, PGP, and GPG: What is the difference?
准备
安装 GPG :
1 | sudo apt update && sudo apt install gpg -y |
安装 nautilus-wipe :
1 | sudo apt install nautilus-wipe -y |
生成主密钥
终端运行:
1 | gpg --expert --full-gen-key |
选择类型
1 | Please select what kind of key you want: |
如上所示,根据个人需要,这里选择了第 11 项。
选择密钥能进行的操作
1 | Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate |
这里依次选择了 S(回车)和 Q(回车)选项,只留下了 Certify 。
选择曲线类型
1 | Please select which elliptic curve you want: |
这里目前推荐选择第一个选项,Curve 25519。
设置密钥的有效期限
1 | Please specify how long the key should be valid. |
根据自己的需要设置有效期限,这里输入了 5y
。
设置杂项
如实填写姓名邮件地址,并设置私钥的访问密码。
生成子密钥
1 | gpg --expert --edit-key [email protected] |
此时,进入了 GPG 命令行。
输入 addkey
,回车。
选择密钥类型
1 | gpg> addkey |
这里选择了第 11 个选项。
选择子密钥能进行的操作
1 | Possible actions for a ECDSA/EdDSA key: Sign Authenticate |
关闭 S 的功能,打开 A 的功能,用 Q 退出。因此这里依次输入了 S(回车)、A(回车)、Q(回车)。
我们这里创建的是用于 Authenticate 的子密钥。
其他设置
与主密钥设置类似,不再赘述。
再生成两个子密钥
重复上述生成子密钥的过程( addkey
),来分别生成用于 Sign 和 Encrypt 的子密钥。
在以下选项中依次选择 10 和 12 即可分别创建这两个子密钥。
1 | gpg> addkey |
最后的结果
1 | sec ed25519/XXXXXXXXXXXXXXXX |
输入 save
保存并退出。
分离主密钥
方法一
导出私钥
导出所有密钥,作为备份:
1 | gpg --output all_secret_keys --export-secret-keys [email protected] |
导出某个子密钥:
1 | gpg --output some_secret_subkeys --export-secret-subkeys AAAAAAAAAAAAAAAA! |
可以单独导出,也可以一同导出,注意 ID 后的感叹号,此符号确保主密钥不会被同时导出,再例如:
1 | gpg --output some_secret_subkeys --export-secret-subkeys AAAAAAAAAAAAAAAA! BBBBBBBBBBBBBBBB! |
删除密钥
删除私钥:
1 | gpg --delete-secret-keys [email protected] |
删除公钥:
1 | gpg --delete-keys [email protected] |
或者,将以上两条命令合为:
1 | gpg --delete-secret-and-public-key [email protected] |
重新导入子密钥
1 | gpg --import some_secret_subkeys |
如此以来,实现了主、子密钥分离
信任密钥
1 | gpg --edit-key [email protected] |
输入 trust
命令:
1 | Please decide how far you trust this user to correctly verify other users' keys |
选择 5 ,输入 quit
退出。
清理
做好导出的私钥的备份,在 nautilus 中 wipe 不需要的文件。
注意:在 SSD 下无法彻底 wipe,请通过全盘加密的方式保护文件。
方法二
备份
备份家目录下的 .gnupg
到加密的移动介质上。
删除主密钥
1 | gpg --with-keygrip --list-key [email protected] |
找到主密钥的 keygrip ,记住。
在 ~/.gnupg/private-keys-v1.d
下删除对应的主密钥文件。
使用
可以指定在移动介质的环境里运行 gpg :
1 | gpg --homedir <dir> <some commands here> |
备份并删除吊销证书
备份
确保 ~/.gnupg/openpgp-revocs.d
已安全备份。
删除
删除上述已备份的文件夹。
显示密钥
1 | gpg --list-secret-keys --keyid-format long |
导出公钥
导出为二进制文件:
1 | gpg --output yourname.gpg --export [email protected] |
导出为文本文件:
1 | gpg --armor --output yourname.txt --export [email protected] |
更改 Passphrase
如需更改私钥密码:
1 | gpg --edit-key [email protected] |
给文件签名
生成二进制签名文件
1 | gpg --sign input.txt |
生成 ASCII 格式签名
1 | gpg --clearsign input.txt |
签名和原文件分离
1 | gpg --armor --detach-sign input.txt |
验证签名文件
1 | gpg --verify input.txt.asc input.txt |
给他人 PGP 公钥签名
导入他人公钥
先获取某人的公钥(从公钥服务器上):
1 | gpg --recv-keys XXXXXXXX |
或者指定一个 keyserver :
1 | gpg --keyserver pgp.mit.edu --recv-keys XXXXXXXX |
或者从文件导入某人的公钥:
1 | gpg --import /tmp/file |
检查一下指纹:
1 | gpg --fingerprint XXXXXXXX |
签名
1 | gpg --sign-key XXXXXXXX |
或者指定使用某个私钥签名:
1 | gpg -u YYYYYYYY --sign-key XXXXXXXX |
或者再要求询问签名的过期日期:
1 | gpg -u YYYYYYY --sign-key --ask-cert-expire XXXXXXXX |
或者再要求询问有效性:
1 | gpg -u YYYYYYY --sign-key --ask-cert-expire --ask-cert-level XXXXXXXX |
导出并发送给别人
1 | gpg --armor --export XXXXXXXX | gpg --encrypt -r XXXXXXXX --armor --output XXXXXXXX-signedBy-YYYYYYYY.asc |
吊销签名
1 | gpg --edit-key XXXXXXXX |
1 | revsig |
1 | gpg --send-key XXXXXXXX |
查看签名:
1 | gpg --list-sigs XXXXXXXX |
加密和解密
加密
1 | gpg --recipient [email protected] --output encrypt.txt --encrypt input.txt |
解密
1 | gpg --decrypt encrypt.txt --output decrypt.txt |
再添加一个 UID
1 | gpg --edit-key [email protected] |
1 | adduid |
选择一个 UID 最为主要 ID:
1 | uid 1 (or 2) |
如果日后需要移除 UID:
1 | gpg --edit-key [email protected] |
1 | uid 1 (or 2) |
延期
1 | gpg --edit-key [email protected] |
延期编号为 n
的密钥:
1 | key n |
重新发布公钥:
1 | gpg --keyserver pgp.mit.edu --send-keys [email protected] |
吊销
注意:吊销之后,需要将公钥再次发布,以做告知。
生成一个吊销证书
1 | gpg --output revoke.asc --gen-revoke AAAAAAAA |
导入吊销证书
1 | gpg --import revoke.asc |
吊销某个子密钥
1 | gpg --edit-key [email protected] |
指定编号为 n
的子密钥吊销:
1 | list |
References
GPG Change Passphrase Secret Key Password Command
Expiration date of key signature
Encrypt and sign with specific secret key
用 PGP 保护代码完整性(五):将子密钥移到一个硬件设备中
用 PGP 保护代码完整性(六):在 Git 上使用 PGP
How to add additional email addresses to your GPG identity
How to revoke a GnuPG/PGP signature on a key
gpg(1) — gnupg — Debian stretch — Debian Manpages
The GNU Privacy Handbook Chapter 1
How to set default uid of gpg key to sign commits and tags in git?