一 把公钥发布到公钥服务器

公钥服务器用于储存和发布用户的公钥以便相互交流,这些服务都是免费的,GnuPG 默认的公钥服务器是 keys.gnupg.net,可以在这里找到更多的服务器。你也可以使用浏览器打开它们的网站,然后把你的公钥复制粘贴上去。当然最直接的是通过命令行。

$ gpg --send-keys ID

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

其中参数:

--send-keys 用于指定待发布的公钥的id。

[root@centos gnupg-2.1.4]# gpg --send-keys F15FE9FE
gpg: sending key F15FE9FE to hkp server keys.gnupg.net

二 导入他人的公钥,加密一个文件

下面我们来做个试验,尝试导入笔者的公钥,然后使用该公钥加密一个文件。通过这个试验就可以学会怎样获取他人的公钥并用它加密信息。

1 在公钥服务器搜索笔者的公钥并导入到本机

使用如下的命令可以搜索到我的公钥:

[root@centos gnupg-2.1.4]# gpg --search-keys cakin
gpg: searching for "cakin" from hkp server keys.gnupg.net
(1)    cakin (cakin) <798102175@qq.com>
      2048 bit RSA key F15FE9FE, created: 2018-10-14, expires: 2019-10-14
Keys 1-1 of 1 for "cakin".  Enter number(s), N)ext, or Q)uit > 1
gpg: requesting key F15FE9FE from hkp server keys.gnupg.net
gpg: key F15FE9FE: "cakin (cakin) <798102175@qq.com>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1

如果有重名的情况,这里会列出多条记录。你可以输入n并回车把搜索结果浏览个遍。当你看到id和uid都跟你要找的那个吻合时,输入搜索结果前面显示的数字就可以把相应的公钥下载到本机。如上面的搜索结果,按数字1并回车就可以把我的公钥导入到本机。输入q并回车可退出搜索。

注:服务 keys.gnupg.net 背后是一组服务器,它们之间的信息同步需要一定的时间,如果你刚刚提交了自己的公钥,可能不会立即搜索就有结果,只要过一段时间(大概1小时)就好了。如果你用的是普通公钥服务器,比如 pgp.mit.edu 则不会有这个问题。

2 如果你确切知道要导入的公钥的id,也可以跳过搜索这步而直接使用如下的命令导入。

[root@centos gnupg-2.1.4]# gpg --recv-keys F15FE9FE
gpg: requesting key F15FE9FE from hkp server keys.gnupg.net
gpg: key F15FE9FE: "cakin (cakin) <798102175@qq.com>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1

其中 F15FE9FE 是我公钥的id,如果把它替换成你朋友的公钥id则为导入你朋友的公钥。

3 导入公钥还有另一种方法:如果我把公钥文件直接发送了给你,你也可以跳过公钥服务器。

下面假设我的公钥文件 public-key.txt 已发送给你,你运行如下命令就可以导入我的公钥了:

[root@centos gnupg-2.1.4]# gpg --import public-key.txt
gpg: key F15FE9FE: "cakin (cakin) <798102175@qq.com>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1

三 核对公钥指纹值并签收指纹(cakin把公钥发送给Alice)

Alice把cakin的公钥导入到自己机器后,就已经可以用它来加密信息或者用于校验cakin的数字签名。不过这样每次操作时都会提示公钥不可信,因为虽然Alice导入了cakin的公钥,但存在导入攻击者的公钥的可能性。所以Alice需要进一步跟cakin核对公钥是否正确,然后签收(sign key)它。

因为公钥有可能出现冒牌货,所以每个公钥里都加入了指纹值,使用下面命令可以查看指纹值:

[root@centos gnupg-2.1.4]# gpg --fingerprint cakin
pub   2048R/F15FE9FE 2018-10-14 [expires: 2019-10-14]
      Key fingerprint = 9B42 B3CC DBA4 B411 ACEA  F0F5 08C9 3BF3 F15F E9FE
uid                  cakin (cakin) <798102175@qq.com>
sub   2048R/E672385C 2018-10-14 [expires: 2019-10-14]

其中:9B42 B3CC DBA4 B411 ACEA  F0F5 08C9 3BF3 F15F E9FE就是这个公钥的指纹值

Alice应该通过打电话或者聊天工具等方式询问cakin并核对指纹值是否一致,如果吻合的话就说明你取得的是真货了。

Alice确定取得的公钥是真货之后,使用如下命令对这个公钥进行签收(sign key):

[root@centos gnupg-2.1.4]# gpg --sign-key cakin

pub  2048R/F15FE9FE  created: 2018-10-14  expires: 2019-10-14  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/E672385C  created: 2018-10-14  expires: 2019-10-14  usage: E   
[ultimate] (1). cakin (cakin) <798102175@qq.com>

"cakin (cakin) <798102175@qq.com>" was already signed by key F15FE9FE
Nothing to sign with key F15FE9FE

Key not changed so no update needed.

四 加密一个文件

使用文本编辑器(比如记事本或者 vim、echo)创建一个名为 message.txt 的文件,里面写上任意一行文字,然后使用如下的命令加密它。

[root@centos gnupg-2.1.4]# cat message.txt
hello
gpg
[root@centos gnupg-2.1.4]# gpg -a --output message-ciper.txt -r cakin -e message.txt

-a 表示输出文本文件格式。

--output 指定输出(即加密后)的文件名。

-r 指定信息的接收者(recipient)公钥的uid,可以是名字也可以是email地址。

-e 表示这次要执行的是加密(encrypt)操作。

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

[root@centos gnupg-2.1.4]# cat message-ciper.txt
-----BEGIN PGP MESSAGE-----
Version: GnuPG v2.0.22 (GNU/Linux)

hQEMA+smgVPmcjhcAQf/Wgs9U6PCiCvlln9Eha7HGgS/Tihvc3o+skB01g2tLUvB
oaxc+b3YyEfQeHwqxsoemDGrw+WMSpzTdzPY46oPmLXF50uwMA65JvoEr98a7Kud
mMjKGtIPrD5lC03KbvFFCngeUzC9N52t08aB1Ui5JhkD9n6qyhGro/qlRA35llmn
tQY6XwBu+MrF6uka3RHhgiijSbWzbAbU4ES8QzW+Djk89R8hherzfEWoG7qdL4ia
CFdXG7TA2wlX6nYnogPR64CZ+Bbs+WMqqbLzMs42e2f1ses9pdeiqnavPekNU9f+
/HuzyhObonmS/O/vXaGoB7qdEz0VbA7IwIubYxzIo9JRARGmyGmBy8XE5NU6Oe61
FqXGdvlXj4mn4akDSdP85wruhUQ3BJijf+8EGeIwxen9QpwMpaJ964mpZz9ohGzB
N8ZO6YXOO52AfhNKrpWjRnJ9
=gY6i
-----END PGP MESSAGE-----

五 解密一个文件

现在假设已经收到你寄过来的加密文件 message-ciper.txt,可以使用如下的命令解密

其中参数:

--output 指定输出(即解密后)的文件名。

-d 表示这次要执行的是解密(decrypt)操作。

GnuPG 程序会自动使用我的私钥来解密信息,最后得到一个跟原始内容一样的文本文件 message-plain.txt。