GnuPG(GNU Privacy Guard或GPG)是一个以GNU通用公共许可证释出的开放源码用于加密或签名的软件,可用来取代PGP。大多数gpg软件仅支持命令行方式,一般人较难掌握。由于gpg软件开放源代码,很难隐藏后门,因此比pgp等商业软件安全。

install gnupg

1
2
whoami@ubuntu:~$ sudo apt-get install gnupg #for ubuntu
whoami@centos:~$ yum install gnupg #for centos

generate key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
whoami@ubuntu:~$  gpg --gen-key
gpg (GnuPG) 1.4.16; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: 已创建目录‘/home/whoami/.gnupg’
gpg: 新的配置文件‘/home/whoami/.gnupg/gpg.conf’已建立
gpg: 警告:在‘/home/whoami/.gnupg/gpg.conf’里的选项于此次运行期间未被使用
gpg: 钥匙环‘/home/whoami/.gnupg/secring.gpg’已建立
gpg: 钥匙环‘/home/whoami/.gnupg/pubring.gpg’已建立
请选择您要使用的密钥种类:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (仅用于签名)
(4) RSA (仅用于签名)
您的选择? 1
RSA 密钥长度应在 1024 位与 4096 位之间。
您想要用多大的密钥尺寸?(2048)
您所要求的密钥尺寸是 2048 位
请设定这把密钥的有效期限。
0 = 密钥永不过期
<n> = 密钥在 n 天后过期
<n>w = 密钥在 n 周后过期
<n>m = 密钥在 n 月后过期
<n>y = 密钥在 n 年后过期
密钥的有效期限是?(0) 0
密钥永远不会过期
以上正确吗?(y/n) y

您需要一个用户标识来辨识您的密钥;本软件会用真实姓名、注释和电子邮件地址组合
成用户标识,如下所示:
“Heinrich Heine (Der Dichter) <[email protected]>”

真实姓名: whoami
电子邮件地址: [email protected]
注释: whoami
您选定了这个用户标识:
“whoami (whoami) <[email protected]>”

更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)? o
您需要一个密码来保护您的私钥。

我们需要生成大量的随机字节。这个时候您可以多做些琐事(像是敲打键盘、移动
鼠标、读写硬盘之类的),这会让随机数字发生器有更好的机会获得足够的熵数。

随机字节不够多。请再做一些其他的琐事,以使操作系统能搜集到更多的熵!
(还需要198字节)

*******如果提示你以上你可以新开一个终端,在命令行执行tree /

.....+++++
+++++
我们需要生成大量的随机字节。这个时候您可以多做些琐事(像是敲打键盘、移动
鼠标、读写硬盘之类的),这会让随机数字发生器有更好的机会获得足够的熵数。

随机字节不够多。请再做一些其他的琐事,以使操作系统能搜集到更多的熵!
(还需要74字节)
............+++++

...+++++
gpg: /home/whoami/.gnupg/trustdb.gpg:建立了信任度数据库
gpg: 密钥 CC5E7372 被标记为绝对信任
公钥和私钥已经生成并经签名。

gpg: 正在检查信任度数据库
gpg: 需要 3 份勉强信任和 1 份完全信任,PGP 信任模型
gpg: 深度:0 有效性: 1 已签名: 0 信任度:0-,0q,0n,0m,0f,1u
pub 2048R/CC5E7372 2015-10-14
密钥指纹 = 96D4 36CC 5871 F7EA 0509 162E 1686 DC44 CC5E 7372
uid whoami (whoami) <[email protected]>
sub 2048R/9F7266CD 2015-10-14

show key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
whoami@ubuntu:~$ gpg --list-keys
/home/whoami/.gnupg/pubring.gpg
-------------------------------
pub 2048R/CC5E7372 2015-10-14
uid whoami (whoami) <[email protected]>
sub 2048R/9F7266CD 2015-10-14

从中我们可以看到刚才生成的钥匙对的公钥部分,其中:

CC5E7372 是这个公钥的id,这个id跟uid都是用于标识这个公钥的,因为uid是用户随便输入的所以会有重复的情况,因此在某些需要明确指定公钥的命令,需要用id而不能用uid表示这个公钥。另外在使用这个id表示一个钥匙时,记得在前面加上”0x”,是零和字母XYZ的X,比如”0xCC5E7372″
2013-04-17 是生成这个公钥的时间,后面括号内的是有效期。
在实际应用中,因为要发送加密信息给你的朋友就需要对方的公钥,所以在本机上可能会有多个朋友的公钥,但私钥往往只有一个,也就是自己的私钥。使用下面命令可以查看本机上的私钥。

whoami@ubuntu:~$ gpg --list-secret-keys

output public key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
whoami@ubuntu:~$ gpg -a --output key.public --export UID
注:你要把其中的 UID 替换成你的名字或者email地址。

其中参数

-a 表示输出文本文件格式。默认输出是二进制格式,因为二进制格式不太方便在网络(比如论坛或者博客)上展示,所以推荐文本格式。
–output 指定输出文件的名字,你可以更改为其他名字。
–export 表示执行输出公钥操作,后面的 UID 为你要输出的公钥的标识。

whoami@ubuntu:~$ cat key.public
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
......
......
-----END PGP PUBLIC KEY BLOCK-----

send public key to public-key server

公钥导出之后,你可以通过各种方式把它发送给你的朋友,比如email或者聊天工具。而
比较方便的是把公钥发布到公钥服务器。

1
2
3
4
5
6
7
8
9
10
11
whoami@ubuntu:~$ gpg --keyserver keys.gnupg.net --send-key PID
gpg: 将密钥‘PID’上传到 hkp 服务器 keys.gnupg.net

注:你要把其中的 PID 替换成你公钥的id。

其中参数:

–keyserver 用于指定公钥服务器,没有特殊需求的话是可以省略这个参数的,不过有些 GnuPG 版本可能需要指定这个参数才能正常工作。
–send-key 用于指定待发布的公钥的id。

好了,至此你已经学会生成钥匙对以及发布公钥了。

use command gpg file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
1、在公钥服务器搜索作者的公钥并导入到本机
whoami@ubuntu:~$ gpg --keyserver keys.gnupg.net --search-key whoami
参数 –search-key 用于指定搜索关键字,可以是uid的名字或者email地址部分。结果大致如下:

gpg: 搜索“whoami”,在 hkp 服务器 keys.gnupg.net 上
(1) whoami (whoami) <[email protected]>
2048 bit RSA key CC5E7372, 创建于:2015-10-14


whoami@ubuntu:~$ gpg --keyserver keys.gnupg.net --recv-key 0xCC5E7372
gpg: 下载密钥‘CC5E7372’,从 hkp 服务器 keys.gnupg.net
gpgkeys: key CC5E7372 not found on keyserver
gpg: 找不到有效的 OpenPGP 数据。
gpg: 合计被处理的数量:0


# 这里需要时间同步,所以不能立即查询到!

如果你朋友已经发送给你了 key.public公钥文件,通过下面命令直接导入你朋友的公钥
whoami@ubuntu:~$ gpg --import key.public

2、核对公钥的指纹值并签收公钥
因为公钥有可能出现冒牌货,所以每个公钥里都加入了指纹值,使用下面命令可以查看指纹值

whoami@ubuntu:~$ gpg --fingerprint
/home/whoami/.gnupg/pubring.gpg
-------------------------------
pub 2048R/CC5E7372 2015-10-14
密钥指纹 = 96D4 36CC 5871 F7EA 0509 162E 1686 DC44 CC5E 7372
uid whoami (whoami) <[email protected]>
sub 2048R/9F7266CD 2015-10-14

确定取得的公钥是真货之后,使用如下命令对这个公钥进行签收(sign key):
whoami@ubuntu:~$ gpg --sign-key whoami

pub 2048R/CC5E7372 创建于:2015-10-14 有效至:永不过期 可用于:SC
信任度:绝对 有效性:绝对

运行上面的命令之后它提示你再确认一次指纹值,输入y并按回车确定。

提示,如果发现获取回来的是冒牌货,可以使用如下的命令删除它:

whoami@ubuntu:~$ gpg --delete-keys whoami

3、加密一个文件
whoami@ubuntu:~$ gpg -a --output mm-ciper.cfg -r [email protected] -e mm.cfg

中参数:

-a 表示输出文本文件格式。
–output 指定输出(即加密后)的文件名。
-r 指定信息的接收者(recipient)公钥的uid,可以是名字也可以是email地址。
-e 表示这次要执行的是加密(encrypt)操作。

执行完毕之后会在当前文件夹产生文件 mm-ciper.cfg,这个就是被加密之后的文件。

注:如果你要加密的是一个二进制文件,则可以省略 -a 参数,这样产生的加密文件的体积会小一些

4、解密一个文件
whoami@ubuntu:~$ gpg --output mm-plain.txt -d mm-ciper.cfg
#注:第一次这里会提示输入密码,为你刚开始使用gpg设置的秘密

其中参数:

–output 指定输出(即解密后)的文件名。
-d 表示这次要执行的是解密(decrypt)操作。
GnuPG程序会自动使用我的私钥来解密信息,最后得到一个跟原始内容一样的文本文件mm-plain.txt。

至此,你已经学会使用 GnuPG 加密解密文件了。

提示1:导入公钥、核对公钥的指纹值、签名公钥这些操作你只需做一次,以后就可以重复多次使用该公钥加密信息并发送给对方。

提示2:如果你想自己体会整个加密和解密过程,可以用自己的公钥加密信息,然后用自己的私钥解密,只需把上面第3步的命令当中的接收者uid([email protected])更改为自己的uid即可。

使用命令行对文件进行数字签名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
1、数字签名一个文件的方法A
whoami@ubuntu:~$ gpg -a -b mm.cfg
其中参数

-a 表示输出文本文件格式。
-b 表示以生成独立的签名文件的方式进行签名。
命令执行完毕之后,会在当前文件夹里产生一个 mm.cfg.asc 的文件,这个文件即签名。现在我应该把原信息文件 mm.cfg 连同签名文件 mm.cfg.asc 一起寄给你,然后你使用如下命令检验:

whoami@ubuntu:~$ gpg --verify mm.cfg.asc
gpg: 于 2015年10月14日 星期三 17时15分18秒 CST 创建的签名,使用 RSA,钥匙号 CC5E7372
gpg: 完好的签名,来自于“whoami (whoami) <[email protected]>”

其中最重要的是 “Good signature” 字样,表示通过检验,否则表示没通过检验(即意味着原信息的内容被篡改或者原信息不是我发出的)。

提示:如果你有多个私钥,在签名时需要加上参数 -u 指定私钥的 uid。

2、数字签名一个文件的方法B
如果不想生成一个独立的签名文件,则还可以用如下的命令进行签名:
whoami@ubuntu:~$ gpg -a --clearsign mm.cfg

跟方法A不同的地方是用参数 –clearsign 替代了参数 -b。参数 clearsign 表示将签名和原信息合并在一起,并生成一个新文件。

命令运行后同样会生成一个文件 mm.cfg.asc,内容如下:
whoami@ubuntu:~$ cat mm.cfg.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
xxx
xxx
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAEBAgAGBQJWHh4HAAoJEBaG3ETMXnNyxGAH/0bDL/J3kcLjbgtJdjrncbN6
ARq6W+V+05jnm8Uv7KlT7I2cs4ujerLY89ahfRdU0LQlW36Gs+GhonOM0JwvuyMP
bpwARW7ZBswWfY6HVgoc3taTlVaoIezYVnlryBXn7Kr7/PJfkZpX/Ig7UiH4wd60
UT/3h1cz/qfx2aH4PSggX6ersj/DadVMHSQVb+0OZrAlBwqbglEj2eZRfBiZMfNF
YK6tTKJKtE2blLemtQh8xAcTWq++BZdR8oFbXE26IoUhNWRz5VkNRMaABduX4+K6
qwiR1/j4N0Ureu7WFQuN/6vhOgd1hDkLQhfPxFMpcehqA/Oqq3XIztBs0Ye9LZc=
=xfIv
-----END PGP SIGNATURE-----

使用如下命令进行检验:
whoami@ubuntu:~$ gpg --verify mm.cfg.asc

使用如下命令可以把原始信息提取出来:
whoami@ubuntu:~$ gpg --output mm-original.txt -d mm.cfg.asc

至此已经讲完 GnuPG 的基本操作了,如果你还想更深入了解它,这里有几篇官方的文档,推荐阅读一下:

迷你Howto教程:http://www.dewinter.com/gnupg_howto/english/GPGMiniHowto.html
迷你Howto教程(中文版): http://www.gnupg.org/howtos/zh/index.html
The GNU Privacy Handbook http://www.gnupg.org/gph/en/manual.html
另外 wiki 对 OpenPGP 的讲解也很有值得阅读:

Pretty Good Privacy http://en.wikipedia.org/wiki/Pretty_Good_Privacy
还有一些本文未提到但会用得上的命令:

Quick’n easy gpg cheatsheet http://irtfweb.ifa.hawaii.edu/~lockhart/gpg/