简述
GnuPG,简称GPG,是一个密码学软件,用于加密、签名通信内容及管理非对称密码学的密钥。GnuPG 是自由软件,遵循 IETF 订定的 OpenPGP 技术标准设计,并与 PGP
保持兼容。
功能 | 能力 | 说明 |
---|---|---|
[C] | Certificating | 认证 / 给其它证书签名 |
[S] | Signing | 签名 |
[A] | Authenticating | 身份验证 |
[E] | Encrypting | 加密 |
GPG 密钥的能力中, [C]、[S]、[A] 均属于签名方案,只有 [E] 是加密方案。 一个主密钥,可以绑定若干个子密钥;这些子密钥有的具备加密功能,有的具备签名功能。 可以理解为,主私钥就是用来生成多个子密钥来使用,而子密钥丢失可以随时废弃,主密钥生成新的子密钥来使用。
安装
官方下载地址:https://www.gnupg.org/download/index.en.html
centOS
CentOS 默认已经安装了 gpg2
代码语言:javascript复制gpg --version
如果需要手动安装,在http://rpmfind.net/ 搜GPG下载:
代码语言:javascript复制wget http://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/gnupg2-2.0.22-5.el7_5.x86_64.rpm
rpm -ivh gnupg2-2.0.22-5.el7_5.x86_64.rpm
macOS
macOS 下安装,可以选择图形界面和命令行两种形式:
1.GPGTools 包含图形界面,下载地址:https://gpgtools.org/
可以直接安装 GPGTools,就可以包含命令行工具,本例安装 GPGTools,但是使用它的命令行进行操作。
2.命令行工具安装:
代码语言:javascript复制brew install gpg
生成私钥
安装后使用命令:gpg
进行后续的操作,生成私钥使用命令:
gpg --gen-key
只需输入姓名、邮件即可生成,输出如下,私钥文件生成目录:/Users/{user_name}/.gnupg/openpgp-revocs.d/ 需要关注用户ID,在操作时很多地方需要用到用户ID,我这里生成的测试用户ID:9F4B9BCF408B96C68E0645805BDF50B192200806
代码语言:javascript复制gpg (GnuPG/MacGPG2) 2.2.40; Copyright (C) 2022 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
注意:使用 “gpg --full-generate-key” 以获得一个全功能的密钥生成对话框。
GnuPG 需要构建用户标识以辨认您的密钥。
真实姓名: liukaitest
电子邮件地址: liukaitest@163.com
您选定了此用户标识:
“liukaitest <liukaitest@163.com>”
更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)? o
我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘
、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数
发生器有更好的机会获得足够的熵。
我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘
、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数
发生器有更好的机会获得足够的熵。
gpg: 吊销证书已被存储为‘/Users/liukai/.gnupg/openpgp-revocs.d/9F4B9BCF408B96C68E0645805BDF50B192200806.rev’
公钥和私钥已经生成并被签名。
pub rsa3072 2023-01-03 [SC] [有效至:2025-01-02]
9F4B9BCF408B96C68E0645805BDF50B192200806
uid liukaitest <liukaitest@163.com>
sub rsa3072 2023-01-03 [E] [有效至:2025-01-02]
列出私链
代码语言:javascript复制gpg --list-secret-keys
输出公钥
项目应用中,需要将公钥输出给其它机器使用。公钥文件(.gnupg/pubring.gpg)以二进制形式储存。 执行命令,需要用到上面生成的用户ID
代码语言:javascript复制gpg --armor --output public-key.txt --export [用户ID]
参数说明:
--armor
:参数可以将其转换为ASCII码显示
--output
:参数指定输出文件名(public-key.txt)
--export:
:指定哪个用户的公钥
导入、导出密钥
导出公钥
导出为公钥文件,--output 参数可以省略,默认文件名也是 public-key.txt
代码语言:javascript复制gpg --armor --output public-key.txt --export [用户ID]
导出私钥
导出需要输入密钥密码。
代码语言:javascript复制gpg -a -o private-file.key --export-secret-keys [用户ID]
导入公钥、私钥
有两种方式:
- 从远GPG公钥服务器导入
- 从公钥文件导入
从公钥文件导入,这种方式很简单,做开源项目,很多项目会在README中说明公钥HASH,就可以拿着HASH或uid从远程导入到本地。
代码语言:javascript复制gpg --recv-keys <keyid/uid>
通过文件导入
代码语言:javascript复制gpg --import [密钥文件]
签名
签名的数据内容有两种形式:
- 二进制
- ASCII
签名会生成签名文件或将签名和文件合并成一个文件。
1.签名数据、生成新文件:原文件和签名生成在同一个文件中
生成结果为二进制的签名文件:
代码语言:javascript复制gpg --sign demo.txt
生成新文件:demo.txt.gpg
,内容为二进制。
生成 ASCII 内容的签名文件。文件名为xxxx.xxx.asc。签名信息添加在文件尾
代码语言:javascript复制gpg --clear-sign 123.txt.gpg
结果
代码语言:javascript复制-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
123123
1231231
12
3123
12
312323
123123123
12
3
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCAAdFiEEeahrV6DakT8NdrWs1m5Gkkp6RHUFAmOz Y4ACgkQ1m5Gkkp6
RHXWNQv/fbhBLdmuvw41nrtqK6exJ6MxX0Kso5NXOp5PleKc5baParHgjEvXEey8
6/krmom2K0W9tQQ0cXQkagDqRIhpSNEr QiG1OZb6tLRLbFPqYCEU9dugc426/xO
4s9/gaLscYo5X8aoOkvO2cdlP/cYNPmI3CUGXJqy9KGVqmfvl8iTbg2LCEmAYqQu
uQdS42XXH8qieEvjCaBj1aC06NVsLmydwlFu3Zah9HVGj2IQmBTXjboz FrYJ4q
iVMuOH4b02dg7Il0h8u636EeUwNVkX 4jJB3 DPenQ37FOxp1vv/miKM4ace7SjX
nmMi oAJnB577dEaOrxnP6wOKcWEd6/GJMRvb1FcLElu46Bsz5UhoQwRmGyuCrNL
2M6j2j4MHzNv4XBLaFv7Lo59TjZVZrghwblL3Y82zcDsak4kBu/GwZCS9/WANjSs
sPFZSVpwe5bg6cFLN35GAcUB590UCbOtN2SMvdWLWeTw4bSeyqcA8wRi0GTU31Tc
yrVpIRH4
=oMT2
-----END PGP SIGNATURE-----
以上两个命令都是将签名添加到文件中。
2.签名数据、生成新文件:sig、asc
1.生成签名,基于二进制格式
如果想生成单独的签名文件,与文件内容分开存放,可以使用detach-sign参数。
代码语言:javascript复制gpg --detach-sign demo.txt
2.生成签名,基于 ASCII 格式
这个命令会在当前目录下生成 xxxx.xxx.sig 这是文件的签名。采用二进制储存。
代码语言:javascript复制gpg --detach-sign --armor demo.txt
这个命令会生成文件的ASCII签名: demo.txt.asc。
代码语言:javascript复制-----BEGIN PGP SIGNATURE-----
iQGzBAABCAAdFiEEeahrV6DakT8NdrWs1m5Gkkp6RHUFAmOz vUACgkQ1m5Gkkp6
RHVfKQv8CptzZlVqHoxq7TpGeg0kuB7WAtnG5yaHqRCWmGAI6RdMa6o6MI/RchtZ
CvBZRZjm4U228cUmN1/pl/wwI91HL97tei/NZ65ke/KgcEnw HrluY 5b8j7SLug
XambZRlfFkdjTuwGM1zgaIhcBpTG4tX pURGtdGRp5jTzNyWP6vVq80oXte85o/N
aZV/GEa5UOgigPnEK09DP3yTsHxhw8y2Rc8kDS5P1AWeE37dxO3NU1NzkWOmct7P
a4g 1cTxL2o3hXCt TYCejqduKLXJjZLJRlU Kie nanEH868GN qGeCOQN2eN3K
5E/sZzR7A3XTNT9gLYrtr7uRlz7 iU4vYsL5SvyB18I84T7Fqa8qM5s9KMIh7wsL
GlHcoE7H7zOkES3U0RyZWTYHrzJ/h8bCm6ErGy4meqWZRzQTgGMpWlAUvx9rU6iS
ZgwWDgc2qLPIEi0PhD6rVl9Kx1Pr3Ai5XJCtbBn41VK5B5Y6tXqheKXoo6n6lEBj
EmTuKvec
=OduX
-----END PGP SIGNATURE-----
3.验证签名 gpg --verify
新版本不需要 --output 参数,但是原文件必须在当前目录下
代码语言:javascript复制gpg --verify demo.txt.gpg
gpg --verify demo.txt.asc
gpg --verify demo.txt.sig
结果:
代码语言:javascript复制gpg: 假定被签名的数据在‘demo.txt’
gpg: 签名建立于 二 1/ 3 17:52:53 2023 CST
gpg: 使用 RSA 密钥 79A86B57A0DA913F0D76B5ACD66E46924A7A4475
gpg: 完好的签名,来自于 “liukai <liukaitest@gmail.com>” [绝对]
4.签名 加密
命令:
代码语言:javascript复制gpg --local-user [发信者ID] --recipient [接收者ID] --armor --sign --encrypt demo.txt
参数说明:
--local-user
:参数指定用发信者的私钥签名
--recipient
:参数指定用接收者的公钥加密
--armor
:参数表示采用ASCII码形式显示
--sign
:参数表示需要签名
--encrypt
:参数表示指定源文件
发信者ID、接收者ID形式:DF9B9C49EAA9298432589D76DA87E80D6294BE9B
5.验证签名
收到别人签名后的文件,需要用对方的公钥验证签名是否为真。verify参数用来验证。
代码语言:javascript复制gpg --verify demo.txt.sig demo.txt
结果
代码语言:javascript复制gpg: 签名建立于 二 1/ 3 16:32:41 2023 CST
gpg: 使用 RSA 密钥 79A86B57A0DA913F0D76B5ACD66E46924A7A4475
gpg: 完好的签名,来自于 “liukai <liukaitest.asho@gmail.com>” [绝对]
总结
主密钥拥有所有的功能,但是在使用上一般不直接使用主密钥,而是多个生成子密来使用。
参考文档
https://gnupg.org/