使用GPG加密解密数据详细教程
GnuPG(通常称为 GPG)是一种称为 PGP(Pretty Good Privacy)的标准实现。它使用“公用”和“私有”密钥系统来加密和签署消息或数据。
- 公钥publicKey : 可以发给任何人,其他人用
公钥
加密发送的数据内容给私钥
拥有者,接收者使用私钥
解密获取明文内容。 - 私钥PrivateKey : 私人拥有(不能发给别人),用于解密使用
公钥
加密的消息以及签名消息。
使用GPG生成密钥对
Linux系统提供了gpg
命令工具,生成GPG密钥对方法:
gpg --generate-key
注意:如果您希望能够向密钥添加注释、更改位大小(例如 RSA 2048 或 4096)或算法,或您可能希望调整的其他额外密钥选项,则应改用gpg --full-generate-key
:
gpg --full-generate-key
查看创建后的密钥对
gpg --list-keys
gpg -K --fingerprint
导出公钥方法(使用公钥指纹串后8位即可):
gpg --export xxxxyyyy
操作示例:
# List the keys you own (have the private key for)
$ gpg -K --fingerprint
sec rsa4096 2019-03-02 [SC] [expires: 2021-03-01]
9ECF 1199 8AD7 A743 7353 BC57 0E66 E4DE A98A 4921
uid [ultimate] John Doe <[email protected]>
ssb rsa4096 2019-03-02 [E] [expires: 2021-03-01]
# Take the last 8 characters of that string of random letters and numbers and remove the space
$ gpg -a --export A98A4921 > john_doe.asc
通过文件获取公钥
通过公钥文件导入公钥,命令如下:
gpg --import privex.io.asc
从Key服务器获取公钥
有时候我们可以从key服务器上获取公钥信息。
一条命令即可指定从hkps://keys.openpgp.org
获取公钥:
gpg --keyserver hkps://keys.openpgp.org --recv-keys 288DD1632F6E8951
当然也可以通过配置gnupg.conf文件设置key服务器:
# Ensure your user's .gnupg folder exists, so we can create / append to the config files
mkdir -p ~/.gnupg
# You should probably run this command to set keys.openpgp.org as your
# default keyserver (fastest and most reliable as of Jan 2021)
echo "keyserver hkps://keys.openpgp.org" | tee -a ~/.gnupg/dirmngr.conf | tee -a ~/.gnupg/gpg.conf
通过名字或者Email查找
可以通过名字或者email
查找获取公钥信息,命令如下:
$ gpg --keyserver hkps://keys.openpgp.org --search-keys [email protected]
gpg: data source: https://keys.openpgp.org:443
(1) Privex Billing Department (Billing Department at Privex Inc. https
Privex Network Operations (NOC) <[email protected]>
Privex Sales (Privex Sales Team at Privex Inc. https
Privex Server Support (Server Support at Privex Inc. https
Privex Support (Shared key by Privex Inc. support team for Jan 2021 to
4096 bit RSA key 288DD1632F6E8951, 创建于:2021-01-19
Keys 1-1 of 1 for "[email protected]". 输入数字以选择,输入 N 翻页,输入 Q 退出 >
如上,找到一个公钥信息, 输入数字1
回车即可添加对应的公钥信息了。
使用名称搜索公钥信息如下:
gpg --keyserver hkps://keyserver.ubuntu.com --search-keys privex.io
找到多个公钥信息时,确认找到需要的公钥信息输入对应数字即可添加。
加密并发送解密后数据
编辑文件message.txt
,输入内容: Hello world!
,然后使用如下命令加密文件:
gpg -a -r 288DD1632F6E8951 -e message.txt
加密后会生成message.txt.asc
加密文件,内容类似如下:
$ cat message.txt.asc
-----BEGIN PGP MESSAGE-----
hF4DMQK+fLHv3TYSAQdA01XrBpaSji1GnxuLE/UxS75U54IGcBiOiOvmnf92kQAw
FIwhUyRngLJ8tU5bT08GbmyEoU4lRsBWKdGxQ0Np1b8/9GD/HZTahlh2Ul4kPsX0
0lMB9OlrtBZpBVIy/c9d4+Zb2g7uwLBpl2ZK+Zct4KrKyBKEDCwRX+aCCJdhqjH/
bPGewZeg22Cm3H1/JJJFgTbtS+OsFQo2QqMq0KBa97uXIl2bcg==
=f7mE
-----END PGP MESSAGE-----
接下来,将加密的message.txt.asc
文件发送给私钥所有者即可。
解密数据
比如我们接收到了发送来的message.txt.asc
内容并保存为reply.txt.asc
文件,接下来我们可以解密获取明文数据了。
解密数据命令如下:
gpg -d reply.txt.asc
签名和验证签名
文件加密了,但不能说明文件是否被他人修改了, 因此我们需要对文件进行签名
来证明文件没有被修改过。
签名有如下三种方法,推荐使用第三种方法,数据和签名文件分离。但这三种方法都很有用,只是适用场合作用不同而已。
方法一:签名并压缩数据,命令如下:
gpg -s / --sign message.txt
生成一个不可读的message.txt.gpg
文件,同时包含加密的数据。
方法二:签名并保证数据可读,好处是收到的内容直接可读,但可以通过签名验证可读内容是否一致。
gpg --clearsign message.txt
签名后的内容如下:
[email protected] $ cat message.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
hello world
lorem ipsum dolor
this message is from john doe!
-----BEGIN PGP SIGNATURE-----
iQFFBAEBCAAvFiEEp6Qc+4bcuOcca8Lgn9ZPRRB4iSoFAmAKXEgRHGpvaG5AZXhh
bXBsZS5jb20ACgkQn9ZPRRB4iSoo/Af+JyG6r7FhZKPpaQ+nVu0zv3X+EbEqHGy2
SkBlSu3knbTrDsNmGT3offk7PDdyhtScvCauLcfVmRum9pLTRjoOq1qAewMSZhjk
TmOFgC4BUAVE5wsSG4gvgfRU9W4zijDCSXo6L9zSejIsIifj++w8oCR2KqtizVGa
3dzTOudIqUjV8yJr+6uAHfyPo0DRyy3C97s4ZLCJkl8Dr4xNRUPpvk9SSjHtVPOm
eSrO5GEGSkw/h74Cb/AwYJMVgGdOqDTe0pvJUHetw7d9zBjYMf5iUeaUCn7CwrSl
R35cTc9XNejA2vXimFwPiADkhoT5mRPX4Z5j3fm08HjO5tyJN0DDUQ==
=VDen
-----END PGP SIGNATURE-----
方法三:生成单独的签名文件,推荐
使用将签名写进另一个文件的做法,常常会配合-a
选项一起用(输出.asc
文件,否则输出.sig
二进制文件),命令如下:
gpg -u [email protected] -a -b message.txt
签名后生成的message.txt.asc
文件内容如下:
-----BEGIN PGP SIGNATURE-----
iQFFBAABCAAvFiEEp6Qc+4bcuOcca8Lgn9ZPRRB4iSoFAmAKXdMRHGpvaG5AZXhh
bXBsZS5jb20ACgkQn9ZPRRB4iSqkRgf/W2/XkhI0tyi4eRQRAS82sfnf4snUU8WS
U7S+PnbMDHdtNfDHQQRp3ygm0YcfNDeIa1KUT+7IsgKnmEDNQLBldTX4C776ibT9
cnUJCBj+qFfDcw2DtpMkbKnOHyvhmkkHaN09dXbcwAYP7B5ytuR066DeYz3EOIlK
12WiK8v/TxDpXiVLsgz9huOj6YkuhC/JISK6kVf56j4sMI5O2h0yV87CqVx6gmEK
NeQHAEM2mdpiVUwObzj+XDYw7/LyCYsxrDUEM6hqNAXUH9S+VhAl4ywZ2Q8fQCrO
hnqFgoSsunIZTm0iNVNzJGkkUhIFqJ7yTNS1nG+5t9TEBo3VQUvtdw==
=Ugoy
-----END PGP SIGNATURE-----
加密同时签名也是可以的
发送数据时,通常既要签名又要加密,命令如下:
gpg -u [email protected] -r [email protected] -a -b -e message.txt
之后,收到的人解密时自动进行签名验证了。
验证签名
签名的作用是防止我们收到的数据被他人恶意篡改,比如植入木马或病毒等等。为了安全我们需要验证为止来源软件的签名。
验证签名方法如下:
gpg --verify message.txt.asc
验证后,正常显示信息如下:
gpg: 假定被签名的数据在‘message.txt’
gpg: 签名建立于 2021年12月08日 星期三 22时05分50秒 CST
gpg: 使用 RSA 密钥 A7A41CFB86DCB8E71C6BC2E09FD64F451078892A
gpg: 签发者 "[email protected]"
gpg: 完好的签名,来自于 john <[email protected]>” [绝对]
显示为
完好的签名
。
但如果message.txt
被他人篡改就会出现如下信息:
gpg: 假定被签名的数据在‘message.txt’
gpg: 签名建立于 2021年03月08日 星期三 22时05分50秒 CST
gpg: 使用 RSA 密钥 A7A41CFB86DCB8E71C6BC2E09FD64F451078892A
gpg: 签发者 "[email protected]"
gpg: 已损坏的签名,来自于 john <[email protected]>” [绝对]
显示为
已损坏的签名
,此时我们可以确认文件被篡改过了,不建议再使用了。
信任他人提供的公钥
默认情况下,GPG不信任导入的公钥,使用公钥加密数据时会提示如下信息:
[[email protected] /]# gpg -r [email protected] -ae hello.txt
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2023-01-22
gpg: E3069E994C92D942: There is no assurance this key belongs to the named user
sub rsa4096/E3069E994C92D942 2021-01-19 Privex Support (Shared key by Privex Inc. support team for Jan 2021 to 2023)
Primary key fingerprint: 17E8 77C3 5C3E 886A 5232 6C6A 288D D163 2F6E 8951
Subkey fingerprint: AEBC 3439 6D4B ABE9 818D 0D37 E306 9E99 4C92 D942
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)
如果你不想每次都有这样的提示,可以使用下面命令签名这个导入的公钥:
gpg --lsign-key 288DD1632F6E8951
之后,再使用这个公钥加密数据时就不会出现安全提示了。