本文介绍gpg的简单介绍和使用。
什么是GPG ¶
GNU Privacy Guard(GnuPG 或 GPG)是一个密码学软件,用于加密、签名通信内容及管理非对称密码学的密钥。GnuPG 是自由软件,遵循 IETF 订定的 OpenPGP 技术标准设计,并与 PGP 保持兼容。
GnuPG 是自由软件基金会的 GNU 计划的一部分,曾受德国政府资助。
Wikipeida https://zh.wikipedia.org/zh-cn/GnuPG
安装密钥 ¶
Debian系列:
1 | sudo apt install gnupg |
安装完后,可以执行
1 | gpg --gen-key |
你应该会看到形如:
1 | gpg (GnuPG) 2.2.27 |
则安装成功。
生成密钥和撤销证书 ¶
简略版本
1 | gpg --gen-key |
详细版本
1 | gpg --generate-key |
详细版本下,它会按顺序询问你:
1 | 请选择您要使用的密钥种类: |
第一段是版权声明,然后让用户自己选择加密算法。默认选择第一个选项,表示加密和签名都使用RSA算法。
然后,系统就会问你密钥的长度。
1 | RSA 密钥长度应在 1024 位与 4096 位之间。 |
密钥越长越安全,默认是3072位,如欲默认,直接回车即可。
接着,设定密钥的有效期。
1 | 请设定这把密钥的有效期限。 |
一般新手上路就选0吧。
系统接下来让你确认。确认后,系统会让你提供个人信息:
1 | 您需要一个用户标识来辨识您的密钥;本软件会用真实姓名、注释和电子邮件地址组合成用户标识,如下所示: |
“真实姓名”一栏不用傻乎乎地真填了,填你的英文名就行。“注释”可以空着。
然后,你的"用户ID"生成了。系统会要求你确定或者修改或者退出。
接着,系统会让你设定一个私钥的密码。这是为了防止误操作,或者系统被侵入时有人擅自动用私钥。
然后,系统就开始生成密钥了,这时会要求你做一些随机的举动,以生成一个随机数。
1 | 我们需要生成大量的随机字节。这个时候您可以多做些琐事(像是敲打键盘、移动鼠标、读写硬盘之类的),这会让随机数字发生器有更好的机会获得足够的熵数。 |
很快,系统提示密钥已经生成了。
1 | gpg: 密钥 xxxxxxxxxxxx 被标记为绝对信任 |
请注意上面的字符串xxxxxxxxxx,这是"用户ID"的Hash字符串,可以用来替代"用户ID"。
这时,最好再生成一张"撤销证书",以备以后密钥作废时,可以请求外部的公钥服务器撤销你的公钥。
这时,最好再生成一张"撤销证书",以备以后密钥作废时,可以请求外部的公钥服务器撤销你的公钥。
1 | gpg --generate-revocation [用户ID] |
上面的"用户ID"部分,可以填入你的邮件地址或者Hash字符串(以下同)。
密钥管理 ¶
列出密钥 ¶
1 | gpg --list-keys |
也可以
1 | gpg --list-keys [用户ID] |
前者显示结果例子如下:
1 | /home/ruanyf/.gnupg/pubring.gpg |
第一行显示公钥文件名(pubring.gpg),第二行显示公钥特征(4096位,Hash字符串和生成时间),第三行显示"用户ID",第四行显示私钥特征。
如果你要从密钥列表中删除某个密钥,可以使用delete-key参数。
1 | gpg --delete-key [用户ID] |
输出密钥 ¶
公钥文件(.gnupg/pubring.gpg)以二进制形式储存,armor参数可以将其转换为ASCII码显示。
1 | gpg --armor --output public-key.txt --export [用户ID] |
"用户ID"指定哪个用户的公钥,output参数指定输出文件名(public-key.txt)。
类似地,export-secret-keys参数可以转换私钥。
1 | gpg --armor --output private-key.txt --export-secret-keys |
上传公钥 ¶
公钥服务器是网络上专门储存用户公钥的服务器。send-keys参数可以将公钥上传到服务器。
1 | gpg --send-keys [用户ID] --keyserver hkp://subkeys.pgp.net |
使用上面的命令,你的公钥就被传到了服务器subkeys.pgp.net,然后通过交换机制,所有的公钥服务器最终都会包含你的公钥。
由于公钥服务器没有检查机制,任何人都可以用你的名义上传公钥,所以没有办法保证服务器上的公钥的可靠性。通常,你可以在网站上公布一个公钥指纹,让其他人核对下载到的公钥是否为真。fingerprint参数生成公钥指纹。
1 | gpg --fingerprint [用户ID] |
输入密钥 ¶
除了生成自己的密钥,还需要将他人的公钥或者你的其他密钥输入系统。这时可以使用import参数。
1 | gpg --import [密钥文件] |
为了获得他人的公钥,可以让对方直接发给你,或者到公钥服务器上寻找。
1 | gpg --keyserver hkp://subkeys.pgp.net --search-keys [用户ID] |
正如前面提到的,我们无法保证服务器上的公钥是否可靠,下载后还需要用其他机制验证.
加密和解密 ¶
加密 ¶
假定有一个文本文件demo.txt,怎样对它加密呢?
encrypt参数用于加密。
1 | gpg --recipient [用户ID] --output demo.en.txt --encrypt demo.txt |
recipient参数指定接收者的公钥,output参数指定加密后的文件名,encrypt参数指定源文件。运行上面的命令后,demo.en.txt就是已加密的文件,可以把它发给对方。
解密 ¶
对方收到加密文件以后,就用自己的私钥解密。
1 | gpg --decrypt demo.en.txt --output demo.de.txt |
decrypt参数指定需要解密的文件,output参数指定解密后生成的文件。运行上面的命令,demo.de.txt就是解密后的文件。
GPG允许省略decrypt参数。
1 | gpg demo.en.txt |
运行上面的命令以后,解密后的文件内容直接显示在标准输出。
签名 ¶
对文件签名 ¶
有时,我们不需要加密文件,只需要对文件签名,表示这个文件确实是我本人发出的。sign参数用来签名。
1 | gpg --sign demo.txt |
运行上面的命令后,当前目录下生成demo.txt.gpg文件,这就是签名后的文件。这个文件默认采用二进制储存,如果想生成ASCII码的签名文件,可以使用clearsign参数。
1 | gpg --clearsign demo.txt |
运行上面的命令后 ,当前目录下生成demo.txt.asc文件,后缀名asc表示该文件是ASCII码形式的。
如果想生成单独的签名文件,与文件内容分开存放,可以使用detach-sign参数。
1 | gpg --detach-sign demo.txt |
运行上面的命令后,当前目录下生成一个单独的签名文件demo.txt.sig。该文件是二进制形式的,如果想采用ASCII码形式,要加上armor参数。
1 | gpg --armor --detach-sign demo.txt |
签名+加密 ¶
上一节的参数,都是只签名不加密。如果想同时签名和加密,可以使用下面的命令。
1 | gpg --local-user [发信者ID] --recipient [接收者ID] --armor --sign --encrypt demo.txt |
local-user参数指定用发信者的私钥签名,recipient参数指定用接收者的公钥加密,armor参数表示采用ASCII码形式显示,sign参数表示需要签名,encrypt参数表示指定源文件。
验证签名 ¶
我们收到别人签名后的文件,需要用对方的公钥验证签名是否为真。verify参数用来验证。
1 | gpg --verify demo.txt.asc demo.txt |
举例来说,openvpn网站就提供每一个下载包的gpg签名文件。你可以根据它的说明,验证这些下载包是否为真。