如何使用 GPG 管理密钥

Contents
  1. 1. 了解
  2. 2. 准备
  3. 3. 生成主密钥
    1. 3.1. 选择类型
    2. 3.2. 选择密钥能进行的操作
    3. 3.3. 设置密钥的长度
    4. 3.4. 设置密钥的有效期限
    5. 3.5. 设置杂项
  4. 4. 生成子密钥
    1. 4.1. 选择密钥类型
    2. 4.2. 选择子密钥能进行的操作
    3. 4.3. 其他设置
    4. 4.4. 再生成一个子密钥
    5. 4.5. 最后的结果
  5. 5. 分离主密钥
    1. 5.1. 方法一
      1. 5.1.1. 导出私钥
      2. 5.1.2. 删除密钥
      3. 5.1.3. 重新导入子密钥
      4. 5.1.4. 信任密钥
      5. 5.1.5. 清理
    2. 5.2. 方法二
      1. 5.2.1. 备份
      2. 5.2.2. 删除主密钥
      3. 5.2.3. 使用
    3. 5.3. 备份并删除吊销证书
      1. 5.3.1. 备份
      2. 5.3.2. 删除
  6. 6. 显示密钥
  7. 7. 导出公钥
  8. 8. 更改 Passphrase
  9. 9. 给文件签名
    1. 9.1. 生成二进制签名文件
    2. 9.2. 生成 ASCII 格式签名
    3. 9.3. 签名和原文件分离
    4. 9.4. 验证签名文件
  10. 10. 给他人 PGP 公钥签名
    1. 10.1. 导入他人公钥
    2. 10.2. 签名
    3. 10.3. 导出并发送给别人
    4. 10.4. 吊销签名
  11. 11. 加密和解密
    1. 11.1. 加密
    2. 11.2. 解密
  12. 12. 再添加一个 UID
  13. 13. 延期
  14. 14. 吊销
    1. 14.1. 生成一个吊销证书
    2. 14.2. 导入吊销证书
    3. 14.3. 吊销某个子密钥
  15. 15. References

本文最后更新于 2022 年 1 月 23 日


本文以 Ubuntu 21.10 为例,介绍如何使用 GPG( GNU Privacy Guard )软件进行密钥的管理,以及 GPG 的基本使用方法及日常使用建议。


了解

请先了解,什么是 PGP、OpenPGP、GPG 。

以下是有用的链接:

PGP - 维基百科

GnuPG - 维基百科

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
2
3
4
5
6
7
8
9
10
11
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(9) ECC and ECC
(10) ECC (sign only)
(11) ECC (set your own capabilities)
Your selection? 8

如上所示,根据个人需要,这里选择了第 8 项。

选择密钥能进行的操作

1
2
3
4
5
6
7
8
9
Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished

Your selection?

这里依次选择了 S 、E 、和 Q 选项,只留下了 Certify 。

设置密钥的长度

1
2
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096

这里设置为 4096 。

设置密钥的有效期限

1
2
3
4
5
6
7
8
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)

根据自己的需要设置有效期限,这里输入了 2y

设置杂项

如实填写姓名邮件地址,并设置私钥的访问密码。


生成子密钥

1
gpg --expert --edit-key [email protected]

此时,进入了 GPG 命令行。

输入 addkey ,回车。

选择密钥类型

1
2
3
4
5
6
7
8
9
10
11
12
13
gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(12) ECC (encrypt only)
(13) Existing key
Your selection? 8

这里选择了第 8 个选项。

选择子密钥能进行的操作

1
2
3
4
5
6
7
8
9
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt

(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished

Your selection?

关闭 S 或 E 的功能,用 Q 退出。这里输入了 E 、Q 。

其他设置

与主密钥设置类似,不再赘述。

再生成一个子密钥

重复上述生成子密钥的过程( addkey ),注意,在选择子密钥能进行的操作时,选择与上次不同的选项,故本例输入了 S 、Q 。

最后的结果

1
2
3
4
5
6
7
8
sec  rsa4096/XXXXXXXXXXXXXXXX
created: 2016-10-08 expires: never usage: C
trust: ultimate validity: ultimate
ssb rsa4096/AAAAAAAAAAAAAAAA
created: 2016-10-08 expires: never usage: S
ssb rsa4096/BBBBBBBBBBBBBBBB
created: 2016-10-08 expires: never usage: E
[ultimate] (1). Your Name <[email protected]>

输入 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
2
3
4
5
6
7
8
9
10
11
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu

Your decision? 5

选择 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
2
3
gpg --edit-key [email protected]
gpg> passwd
gpg> quit

给文件签名

生成二进制签名文件

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
2
revsig
save
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
2
3
uid 1 (or 2)
primary
save

如果日后需要移除 UID:

1
gpg --edit-key [email protected]
1
2
3
uid 1 (or 2)
revuid
save

延期

1
gpg --edit-key [email protected]

延期编号为 n 的密钥:

1
2
3
key n
expire
save

重新发布公钥:

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
2
3
4
list
key n
revkey
save

References

The GNU Privacy Handbook

Exchanging keys

GPG 密鑰的「正確」用法

GPG Change Passphrase Secret Key Password Command

Expiration date of key signature

F21/signing-gpg-keys.md

Encrypt and sign with specific secret key

用 PGP 保护代码完整性(一): 基本概念和工具

用 PGP 保护代码完整性(二):生成你的主密钥

用 PGP 保护代码完整性(三):生成 PGP 子密钥

用 PGP 保护代码完整性(四):将主密钥移到离线存储中

用 PGP 保护代码完整性(五):将子密钥移到一个硬件设备中

用 PGP 保护代码完整性(六):在 Git 上使用 PGP

用 PGP 保护代码完整性(七):保护在线帐户

Keysigning

PGP Key Signing

How to add additional email addresses to your GPG identity

Revoke signature from key

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?

How to remove an email address from a GPG key

2021 年,用更现代的方法使用 PGP(上)

2021 年,用更现代的方法使用 PGP(中)

2021 年,用更现代的方法使用 PGP(下)

续期过期的 GPG 密钥

Mastodon