加密的一个简单但又实用的任务就是发送加密电子邮件。多年来,为电子邮件进行加密的标准一直是PGP(Pretty Good Privacy)。程序员Phil Zimmermann特别为电子邮件的保密编写的PGP。这个软件非常好用,迅速流传开来,成了许多程序员的必备工具。但是,它是商业软件,不能自由使用。作为PGP的替代,如今已经有一个开放源代码的类似产品可供使用。GPG(Gnu Privacy Guard),它不包含专利算法,能够无限制的用于商业应用。
环境
- RHEL7.2
默认以安装GPG - GPG 2.0.22
libgcrypt 1.5.3
使用方法
生成密钥
使用--gen-key
生成一副新的密钥对
1 | gpg --gen-key |
第一段是版权声明,然后让用户自己选择加密算法。默认选择第一个选项,表示加密和签名都使用RSA算法。
1 | RSA 密钥长度应在 1024 位与 4096 位之间。 |
这一步要让我们输入密钥长度,长度越长越安全,默认为2048。
1 | 您所要求的密钥尺寸是 2048 位 |
如果密钥只是个人使用,并且你很确定可以有效保管私钥,建议选择第一个选项,即永不过期。注意,如果想设置在2年后过期,那么应该输入2y,然后回车 回答完上面三个问题以后,系统让你确认。
1 | 密钥于 日 10/ 8 11:20:32 2017 CST 过期 |
到这里,我们对要生成的密钥的配置已经完成了,然后我们还需要一个标识,接下来按照要求依次输入就行了
1 | You need a user ID to identify your key; the software constructs the user ID |
输入o
确定,然后在弹出的窗口输入密码
1 | 我们需要生成大量的随机字节。这个时候您可以多做些琐事(像是敲打键盘、移动 |
请注意上面的字符串”74A64469”,这是”用户ID”的Hash字符串,可以用来替代”用户ID”。到此为止,我们已经完成了生成公钥和私钥的任务了,文件在/home/XXXX/.gnupg/pubring.gpg
这时,最好再生成一张”撤销证书”,以备以后密钥作废时,可以请求外部的公钥服务器撤销你的公钥。使用--gen-revoke 74A64469
进行,此处不再赘述。
查看密钥列表
使用--list-keys
列出当前用户已有的密钥
1 | gpg --list-keys |
第一行显示公钥文件名(pubring.gpg),第二行显示公钥特征(2048位,RSA,Hash字符串和生成时间),第三行显示”用户ID”,第四行显示私钥特征(格式与公钥相同)。
如果你要从密钥列表中删除某个密钥,可以使用delete-key参数gpg --delete-key [用户ID]
输出密钥
** 公钥导出 **
公钥文件(.gnupg/pubring.gpg)以二进制形式储存,armor参数可以将其转换为ASCII码显示。gpg --armor --output public-key.txt --export [用户ID]
** 私钥导出 **
export-secret-keys参数可以转换私钥
1 | gpg --armor --output private-key.txt --export-secret-keys |
上传公钥
公钥服务器是网络上专门储存用户公钥的服务器。send-keys参数可以将公钥上传到服务器gpg --send-keys [用户ID] --keyserver hkp://subkeys.pgp.net
使用上面的命令,你的公钥就被传到了服务器subkeys.pgp.net,然后通过交换机制,所有的公钥服务器最终都会包含你的公钥。
由于公钥服务器没有检查机制,任何人都可以用你的名义上传公钥,所以没有办法保证服务器上的公钥的可靠性。通常,你可以在网站上公布一个公钥指纹,让其他人核对下载到的公钥是否为真。fingerprint参数生成公钥指纹。gpg --fingerprint [用户ID]
输入密钥
除了生成自己的密钥,还需要将他人的公钥或者你的其他密钥输入系统。这时可以使用import参数gpg --import [密钥文件]
为了获得他人的公钥,可以让对方直接发给你,或者到公钥服务器上寻找gpg --keyserver hkp://subkeys.pgp.net --search-keys [用户ID]
或者
1 | gpg --recv-keys E82E4209 |
加密和解密
使用--encrypt
参数用于加密。假设有一个原始文件test.txt
** 使用公钥(Hash字符串)加密:**
1 | gpg --recipient 74A64469 --output test_en.txt --encrypt test.txt |
--recipient
参数指定接收者的公钥--output
参数指定加密后的文件名--encrypt
参数指定源文件
** 使用私钥解密:**
1 | gpg test_en.txt |
签名
有时,我们不需要加密文件,只需要对文件签名,表示这个文件确实是我本人发出的。--sign
参数用来签名
1 | gpg --sign test.txt |
然后生成了一个test.txt.gpg文件,我们打开这个文件后,发现这也是一个二进制的数据,这并不是加密后的数据,与上边的二进制数据不一样。
如果想生成ASCII码的签名文件,可以使用--clearsign
参数
1 | gpg --clearsign test.txt |
然后生成了一个test.txt.asc文件。
如果想生成单独的签名文件,与文件内容分开存放,可以使用--detach-sign
参数
1 | gpg --detach-sign test.txt |
多产生一个,sig
的二进制签名文件,如果想采用ASCII码形式,要加上--armor
参数。
签名+加密
如果想同时签名和加密,可使用这种格式gpg --local-user [发信者ID] --recipient [接收者ID] --armor --sign --encrypt test.txt
--local-user
参数指定用发信者的私钥签名--recipient
参数指定用接收者的公钥加密--armor
参数表示采用ASCII码形式显示--sign
参数表示需要签名--encrypt
参数表示指定源文件
验证签名
收到别人签名后的文件,需要用对方的公钥验证签名是否为真。使用--verify
参数用来验证
1 | gpg --verify test.txt.sig test.txt |