PGP密钥创建及GPG使用
PGP (Pretty Good Privacy) 是一种非对称加密机制,有一个公钥和私钥对,其中公钥公开存储在公网上,私钥由个人安全的保存在本地。
一个简单的使用场景是 读者使用我的公钥 F1C68AB4
加密一个文件,如 abc.txt -> abc.txt.gpg
并发送给我,我收到这个 abc.txt.gpg
文件后,通过我的本地私钥来解密这个文件到 abc.txt
并读取内容。
如果没有私钥,是不可能解读到被加密的内容的,所以可以确保消息内容不被中间人监听、泄露。
系统环境
Archlinux, gpg (GnuPG) 2.1.19
配置
修改 ~/.gnupg/gpg.conf
文件,添加 keyserver
内容如下
修改 ~/.gnupg/gpg-agent.conf
文件,添加如下内容
pinentry-program /usr/bin/pinentry-curses
修改 ~/.gnupg/dirmngr.conf
文件,添加如下内容
杀死所有的 gpg-agent
和 dirmngr
进程
killall dirmngr
1. 获取已被发布的公钥
返回内容如下
gpg: Total number processed: 1
gpg: imported: 1
查看已经导入的公钥
返回内容如下
------------------------
pub rsa2048 2015-12-14 [SC]
EAB335E167A6739677E1879609295FD1F1C68AB4
uid [ unknown] tianyu <xdtianyu*gmail.com>
uid [ unknown] tianyu <admin*xdty.org>
sub rsa2048 2015-12-14 [E]
其中 EAB335E167A6739677E1879609295FD1F1C68AB4
是长 ID, 可以通过 --keyid-format (SHORT/LONG)
参数来查看短一点的 ID,方便与其他人交换。
返回内容如下
------------------------
pub rsa2048/F1C68AB4 2015-12-14 [SC]
EAB335E167A6739677E1879609295FD1F1C68AB4
uid [ unknown] tianyu <xdtianyu*gmail.com>
uid [ unknown] tianyu <admin*xdty.org>
sub rsa2048/F046E25B 2015-12-14 [E]
其中的 rsa2048/F1C68AB4
就是最开始导入的 ID。
2. 创建 PGP 密钥对
注意,如果是 ssh 远程登陆,建议使用 screen 操作,避免 pinentry 出现问题。
交互流程如下
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
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)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
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)
Key does not expire at all
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: myname
Email address: myname@mydomain.com
Comment: test pgp
You selected this USER-ID:
"myname (test pgp) <myname@mydomain.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
┌──────────────────────────────────────────────────────┐
│ Please enter the passphrase to │
│ protect your new key │
│ │
│ Passphrase: ********________________________________ │
│ │
│ <OK> <Cancel> │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ Please re-enter this passphrase │
│ │
│ Passphrase: ********________________________________ │
│ │
│ <OK> <Cancel> │
└──────────────────────────────────────────────────────┘
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 66078F7054E76435 marked as ultimately trusted
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/767FA3A9F943376B4AA469B566078F7054E76435.rev'
public and secret key created and signed.
pub rsa4096 2017-04-13 [SC]
767FA3A9F943376B4AA469B566078F7054E76435
767FA3A9F943376B4AA469B566078F7054E76435
uid myname (test pgp) <myname@mydomain.com>
sub rsa4096 2017-04-13 [E]
再次通过 gpg --list-keys --keyid-format SHORT
命令查看已经导入的公钥
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
/root/.gnupg/pubring.kbx
------------------------
pub rsa2048/F1C68AB4 2015-12-14 [SC]
EAB335E167A6739677E1879609295FD1F1C68AB4
uid [ unknown] tianyu <xdtianyu*gmail.com>
uid [ unknown] tianyu <admi*xdty.org>
sub rsa2048/F046E25B 2015-12-14 [E]
pub rsa4096/54E76435 2017-04-13 [SC]
767FA3A9F943376B4AA469B566078F7054E76435
uid [ultimate] myname (test pgp) <myname*mydomain.com>
sub rsa4096/B8F96DC9 2017-04-13 [E]
可以看到已经生成 ID 为 54E76435
的公钥。
其中的 ultimate
表示完全信任,而 unknown
则表示不能信任是否真的是这个邮箱所有者的公钥,因为 PGP 没有邮箱验证机制,所以需要和对方确认ID。
自己新建的公钥自然是可信的,所以默认是 ultimate
,而导入的公钥不能验证对方填写的邮箱地址,所以是 unknown
。
可以通过 gpg --edit-key F1C68AB4
来更新信任状态,这样在用这个公钥加密的时候就不会弹出信任提示了。
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
pub rsa2048/09295FD1F1C68AB4
created: 2015-12-14 expires: never usage: SC
trust: unknown validity: unknown
sub rsa2048/E1F7D3ADF046E25B
created: 2015-12-14 expires: never usage: E
[ unknown] (1). tianyu <xdtianyu*gmail.com>
[ unknown] (2) tianyu <admin*xdty.org>
gpg> trust
pub rsa2048/09295FD1F1C68AB4
created: 2015-12-14 expires: never usage: SC
trust: unknown validity: unknown
sub rsa2048/E1F7D3ADF046E25B
created: 2015-12-14 expires: never usage: E
[ unknown] (1). tianyu <xdtianyu*gmail.com>
[ unknown] (2) tianyu <admin*xdty.org>
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
Do you really want to set this key to ultimate trust? (y/N) y
pub rsa2048/09295FD1F1C68AB4
created: 2015-12-14 expires: never usage: SC
trust: ultimate validity: unknown
sub rsa2048/E1F7D3ADF046E25B
created: 2015-12-14 expires: never usage: E
[ unknown] (1). tianyu <xdtianyu*gmail.com>
[ unknown] (2) tianyu <admin*xdty.org>
Please note that the shown key validity is not necessarily correct
unless you restart the program.
gpg> save
Key not changed so no update needed.
再次通过 gpg --list-keys --keyid-format SHORT
命令查看已经导入的公钥,可以看到都变成 ultimate
状态。
------------------------
pub rsa2048/F1C68AB4 2015-12-14 [SC]
EAB335E167A6739677E1879609295FD1F1C68AB4
uid [ultimate] tianyu <xdtianyu@gmail.com>
uid [ultimate] tianyu <admin@xdty.org>
sub rsa2048/F046E25B 2015-12-14 [E]
pub rsa4096/54E76435 2017-04-13 [SC]
767FA3A9F943376B4AA469B566078F7054E76435
uid [ultimate] myname (test pgp) <myname@mydomain.com>
sub rsa4096/B8F96DC9 2017-04-13 [E]
使用 gpg --list-secret-keys --keyid-format SHORT
查看生成的私钥信息
------------------------
sec rsa4096/54E76435 2017-04-13 [SC]
767FA3A9F943376B4AA469B566078F7054E76435
uid [ultimate] myname (test pgp) <myname@mydomain.com>
ssb rsa4096/B8F96DC9 2017-04-13 [E]
3. 发布公钥
上一步已经生成了 ID 为 54E76435
的 pgp 密钥对,通过如下命令发布公钥到服务器
返回内容如下
等待几分钟后,在另一个电脑上运行导入命令
返回如下
gpg: key 54E76435 was created 26761 seconds in the future (time warp or clock problem)
gpg: key 54E76435 was created 26761 seconds in the future (time warp or clock problem)
gpg: key 54E76435 was created 26761 seconds in the future (time warp or clock problem)
gpg: key 54E76435 was created 26761 seconds in the future (time warp or clock problem)
gpg: key 54E76435 was created 26761 seconds in the future (time warp or clock problem)
gpg: key 54E76435 was created 26761 seconds in the future (time warp or clock problem)
gpg: key 54E76435: public key "myname (test pgp) <myname@mydomain.com>" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
出现的时间错误是因为主机时间和服务器的时间时区不一至导致的。
---------------------------
gpg: key 54E76435 was created 26648 seconds in the future (time warp or clock problem)
gpg: key 54E76435 was created 26648 seconds in the future (time warp or clock problem)
pub 4096R/54E76435 2017-04-13
uid myname (test pgp) <myname@mydomain.com>
sub 4096R/B8F96DC9 2017-04-13
可以看到成功导入了上一步生成的公钥。
4. 使用公钥加密文件
导入公钥后,就可以通过公钥来加密文件了,使用如下命令测试
gpg -r 54E76435 -e aaa.txt
返回结果如下
pub 4096R/B8F96DC9 2017-04-13 myname (test pgp) <myname@mydomain.com>
Primary key fingerprint: 767F A3A9 F943 376B 4AA4 69B5 6607 8F70 54E7 6435
Subkey fingerprint: 600A 7788 9913 7A6A 7351 C89B C276 C3D1 B8F9 6DC9
It is NOT certain that the key belongs to the person named
in the user ID. If you *really* know what you are doing,
you may answer the next question with yes.
Use this key anyway? (y/N) y
注意这个提示可以通过上文提到的 gpg --edit-key 54E76435
来更新信任状态。
发送生成的 aaa.txt.gpg
文件到含有 54E76435
私钥的机器上。
注意,如果需要生成文本格式的加密内容,可以使用 -a, --armor
参数
之后将生成 aaa.txt.asc
文本文件,内容示例如下
Version: GnuPG v1
hQEMA+H3063wRuJbAQf+ISBZcZWP7Pxm/r4NSAK/M+ArhUw7PY9Cksl8H06BmgnD
...
mEPWYJw4oCmzO4HWENvhSJOOHbg+OzDrbq4AhdfU+gkcBbLiD5B8S76pEmAYBchF
85a2
=DA/w
-----END PGP MESSAGE-----
5. 使用私钥解密文件
通过如下命令解密上一步生成的 aaa.txt.gpg
文件
第一次使用解密命令时会提示输入私钥密码,之后一段时间再解密将不再需要输入密码。
│ Please enter the passphrase to unlock the OpenPGP secret key: │
│ "myname (test pgp) <myname@mydomain.com>" │
│ 4096-bit RSA key, ID C276C3D1B8F96DC9, │
│ created 2017-04-13 (main key ID 66078F7054E76435). │
│ │
│ │
│ Passphrase: ********__________________________________________ │
│ │
│ <OK> <Cancel> │
└────────────────────────────────────────────────────────────────┘
gpg: encrypted with 4096-bit RSA key, ID C276C3D1B8F96DC9, created 2017-04-13
"myname (test pgp) <myname@mydomain.com>"
abc
6. 通过文本密码加密文件
gpg 可以通过文本密码来加密文件,注意这种加密方式就是普通形式的密码加密,不需要密钥对
┌──────────────────────────────────────────────────────┐
│ Enter passphrase │
│ │
│ │
│ Passphrase: *******_________________________________ │
│ │
│ <OK> <Cancel> │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ Please re-enter this passphrase │
│ │
│ Passphrase: *******_________________________________ │
│ │
│ <OK> <Cancel> │
└──────────────────────────────────────────────────────┘
可以将生成的 aaa.txt.gpg
文件发送给其他人,并直接通过密码解密。
7. 添加新的用户 ID 到密钥对并发布更新公钥
可以通过 gpg --edit-key 54E76435
增加新的邮箱地址到密钥对
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
sec rsa4096/66078F7054E76435
created: 2017-04-13 expires: never usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/C276C3D1B8F96DC9
created: 2017-04-13 expires: never usage: E
[ultimate] (1). myname (test pgp) <myname@mydomain.com>
gpg> adduid
Real name: myname2
Email address: myname2@mydomain2.com
Comment: test pgp 2
You selected this USER-ID:
"myname2 (test pgp 2) <myname2@mydomain2.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
sec rsa4096/66078F7054E76435
created: 2017-04-13 expires: never usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/C276C3D1B8F96DC9
created: 2017-04-13 expires: never usage: E
[ultimate] (1) myname (test pgp) <myname@mydomain.com>
[ unknown] (2). myname2 (test pgp 2) <myname2@mydomain2.com>
gpg> trust
sec rsa4096/66078F7054E76435
created: 2017-04-13 expires: never usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/C276C3D1B8F96DC9
created: 2017-04-13 expires: never usage: E
[ultimate] (1) myname (test pgp) <myname@mydomain.com>
[ unknown] (2). myname2 (test pgp 2) <myname2@mydomain2.com>
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
Do you really want to set this key to ultimate trust? (y/N) y
sec rsa4096/66078F7054E76435
created: 2017-04-13 expires: never usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/C276C3D1B8F96DC9
created: 2017-04-13 expires: never usage: E
[ultimate] (1) myname (test pgp) <myname@mydomain.com>
[ unknown] (2). myname2 (test pgp 2) <myname2@mydomain2.com>
gpg> save
再次通过 gpg --list-keys
查看当前的公钥,可以看到新的 UID 已经被加入到密钥对中。
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
/root/.gnupg/pubring.kbx
------------------------
pub rsa4096 2017-04-13 [SC]
767FA3A9F943376B4AA469B566078F7054E76435
uid [ultimate] myname2 (test pgp 2) <myname2@mydomain2.com>
uid [ultimate] myname (test pgp) <myname@mydomain.com>
sub rsa4096 2017-04-13 [E]
通过 gpg --send-key 54E76435
命令更新公钥到服务器。
8. 导出和导入公钥
如果不想通过公网服务器交换公钥,也可以导出公钥文件,交换公钥文件后再导入对方计算机
通过 gpg --list-keys
命令查看当前的公钥,显示如下
------------------------
pub rsa4096 2017-04-13 [SC]
767FA3A9F943376B4AA469B566078F7054E76435
uid [ultimate] myname2 (test pgp 2) <myname2@mydomain2.com>
uid [ultimate] myname (test pgp) <myname@mydomain.com>
sub rsa4096 2017-04-13 [E]
再通过 gpg --export -a 767FA3A9F943376B4AA469B566078F7054E76435
或 gpg --export -a myname
命令导出公钥文本
mQINBFjvsHwBEACxl35XbDv2GhrLg0wW9u2oYxf2AOL/cw22UCiKTjnTYlOj4J0j
t5zMSdsE33FfqI5qmgZBrxhWoIPSb+V0ltIyXHDu9OeM0W4Tj7iNEW4WU+Gdpx9y
......
1MNNkK4EIbOWj29pT7rB4JpsZsjOyhGRL9U5kSNHJxK93yfzvFgWvoxEaQw0kQij
Fjo/bOsGrWaRw951UGAif6i5haHmsvHdPD0R/M4wAb29XWricszbMYCju0ry1pyy
yfY3ETZ3Yo+3BhC5Pxlq3aQM
=KR0j
-----END PGP PUBLIC KEY BLOCK-----
发送这个公钥文本文件给对方后,如保存为 myname.asc
文件,对方可以通过 gpg --import myname.asc
命令导入公钥。返回内容如下
gpg: Total number processed: 1
gpg: unchanged: 1
9. 导出和备份私钥
私钥一旦丢失,被加密的文件将不能解密,所以将私钥备份在安全的地方很重要。可以通过
命令来保存私钥到本地文件。输入密码后会在本地生成 myname.secret.asc
文件,可以备份到 Dropbox
等服务。
之后如果私钥丢失,可以通过 gpg --import myname.secret.asc
命令导入私钥文件。
使用密钥解密文件会要求输入密码,是私钥泄漏后的一个保障,因为私钥太重要,私钥和私钥密码一定不能泄漏。
Tags: gpg gunpg linux pgp
评论:5