本文内容选自以下文章:
- http://irtfweb.ifa.hawaii.edu/~lockhart/gpg/
- https://www.leadroyal.cn/p/502/
- https://zhuanlan.zhihu.com/p/137574731
- https://learnku.com/articles/71598
- https://blog.csdn.net/willingtolove/article/details/122362705
文章目录
GPG基本概念
1. 关于[S],[A],[C],[E]功能
标识含义作用Ssign签名功能Eencrypt加密功能Aauthenticate身份验证功能,在其他协议中用于身份验证,例如SSH TLS。只能通过
--expert
选项制作具有该功能的子公钥。Ccertify认证,主密钥必备能力,且只有主密钥具有
[C]、[S]、[A] 均属于签名方案,只有 [E] 是加密方案。
2. 关于GPG的五个信任级别
GPG 的信任级别分为以下几个等级:
Ultimate
:绝对信任,只会出现在你自己的密钥上。
Full
:完全信任,你相信这个密钥,并信任它可以很好地管理签发密钥。使用这个密钥签名的其他密钥也会受到信任。比如,你完全信任了
小明的密钥
,那么由小明签名过的
小美的密钥
也会受到信任。
Marginal
:相对信任,你相信这个密钥本身,但不确定它签名的密钥是否一定正确。如果一个密钥被至少三个 Marginal 级别的密钥签名,那么该密钥也是可信的。
Never
:绝不信任,这个密钥是完全不可信的。这也许以为着密钥的所有者并不能确保它签名的密钥有效,或是该密钥已被泄露因此不再可信。
Unknown
:未知,这是密钥的默认信任级别,该级别的密钥不会被信任。
3. GPG常见缩写及概念
简写含义key pair密钥对(包含两部分)primary key [master key]主密钥(包括主公钥,主私钥)public keypub主公钥secret keysec主私钥sub-keysub子公钥secret sub-keyssb子私钥key fingerprint密钥指纹
4.用户身份(UID)简介
uid 即 user id
一个 uid 由三个部分组成:
- 全名(一般是实名)
- 注释(用 ( ) 包括)
- 邮箱地址(用 < > 包括)
这三个部分都是可选的,只要有一项即可。
例如:
Han Meimei email@example.com
Han Meimei (Work) hanmm@company.com
Han Meimei (Product) hanmm@company.com
- 一个密钥可以有多个 uid,方便不同场合使用。
- uid 与哪个子密钥无关,uid 是作用于整个密钥的。
- uid 可以随时添加,但已有的 uid 不能修改,只能单独吊销。
- uid 单独吊销后,只需要重新发布公钥即可。
如果你希望只用一个密钥,但某些身份不公开,你需要小心配置你的公钥,不过最好还是另外用一个密钥。
主密匙相关
创建/删除/查看密钥信息
创建新的密钥对
- gpg --gen-key
Generate a new key pair using the current default parameters. This is the standard command to create a new key. In addition to the key a revocation certificate is created and stored in the ‘openpgp-revocs.d’ directory below the GnuPG home directory.
使用当前默认参数生成一个新的密钥对。 这是用于创建一个新的密钥的标准命令。 除了密钥之外,还创建了一个撤销证书并存储在GnuPG 主目录下的 'openpgp-revocs.d’目录下。
注:在笔者的Ubuntu-20.04下,该文件夹路径为"~/.gnupg/openpgp-revocs.d"
- gpg --expert --full-gen-key
启用更多编辑选项的生成密钥对
删除公钥(从你的公钥环中)
gpg --delete-key “User Name”
注:当你的私钥环有与此公钥关联的私钥,你将得到报错!
删除私钥
gpg --delete-secret-key “User Name”
列出公钥环中的密钥
gpg --list-keys
gpg --list-key
gpg -k
列出密钥环中的密钥
gpg --list-secret-keys
gpg --list-secret-key
gpg -K
输出公钥指纹
gpg --fingerprint [UserID]
打印用户UserID的公钥指纹,如果省略UserID则打印所有用户的
导出/导入密钥
导出公钥
gpg --export -a “User Name”-o public.key
-a
表示以ascii形式输出
-o filename
表示输出到文件 filename
导出公钥到文件public.key。
该指令是gpg --export的一个变体,它基本上只能在命令行输出一堆乱码。建议不要使用该代码。
gpg --export -a “User Name”
将用户名的公钥打印到命令行,有一点用。
导出私钥
gpg --export-secret-key -a “User Name” -o private.key
-a
表示以ascii形式输出
-o filename
表示输出到文件 filename
导出私钥到文件private.key。
- 注1:你可能会想通过邮件传输私钥文件,请务必加密,使用未加密的电子邮件发送私钥很危险。
- 注2:关于为什么要导出私钥:- 例1:你可能有多台计算机,且你可能希望所有计算机使用一个密钥对,该代码允许你导出密钥用于在其他计算机上导入。- 例2:假设您是一个小组的成员,并且想为小组创建一个密钥对,一个人可以创建密钥对,然后导出公钥和私钥,将它们提供给该组的其他成员。使组的成员或外部的人可以使用该组公钥加密消息/数据。基本上,您可以创建一个简化的系统,使得只需要一个公钥即可将加密的内容发送给多个收件人。
导入公钥
gpg --import public.key
从文件 public.key 导入公钥
导入私钥
注:
gpg --allow-secret-key-import --import private.key
指令由于
--allow-secret-key-import
已经废除,故无效。
正确步骤如下:
- gpg --import private.key
导入私钥,从输出获得 KEY
- gpg --edit-key KEY trust quit
- 输入 5 , y
修改该私钥的信任等级为[ultimate]而不是[unknown]
上传/下载/更新公钥
上传公钥到公钥服务器
gpg --send-keys “KEY ID”
根据笔者在很多文章查到的内容,这里可以使用UserID,但是经过实测发现会报错
gpg: “xxx” 不是一个用户标识:跳过
,所以提供另一个方法(也是man gpg提供的指令),即使用KEY ID (也可以使用指纹)
以下为man gpg关于该指令的解释
Similar to --export but sends the keys to a keyserver. Fingerprints may be used instead of key IDs. Don’t send your complete keyring to a keyserver — select only those keys which are new or changed by you. If no keyIDs are given, gpg does nothing.
类似--export
的功能但是这个是上传密钥到服务器,指纹可用于替代KeyID,不要上传整个钥匙环——只上传那些新的或修改过的,如果没有KeyIDs参数,gpg什么都不会做
在公钥服务器搜索并导入指定ID的公钥
gpg --keyserver keyserver.ubuntu.com --search-keys [用户ID]
--keyserver hkp://subkeys.pgp.net
指定搜索的服务器对象,缺省为gpg默认的服务器
下载公钥后建议使用
gpg --fingerprint
验证指纹是否符合,若是错误的公钥则删除,若确认无误则
gpg --sign-key [KEYID]
签收公钥(即[完全]信任该公钥)
直接根据KeyID导入公钥
——gpg --recv-keys KeyID
在已知KeyID的情况下使用该指令直接导入,同样可以使用
--keyserver
来指定服务器
更新所有公钥
gpg --refresh-keys
公钥可能已经过期、修改或被吊销,通过该指令更新所有公钥,同样可以使用
--keyserver
参数指定服务器
加密/解密/签名相关
加密文件
gpg -a -r “Receiver” -o output.enc -e filename
-a
表示以ascii形式输出,方便阅读。如果加密文件为二进制可省略该项,可能可以减小部分大小。
-o output.enc
表示将加密后文件输出到_output.enc_文件中,如果省略该项,默认输出到 filename.gpg 文件中,注意:经实测,不能使用
> file
指定输出文件。
-r "Receiver"
用于指定接收用户,可多次使用
-r xxx
以实现对多个用户的加密,也可省略该项,会有交互式指令来添加。
-e
指定加密的文件名,经测试该项必须放于最后。
解密文件
gpg -o mydata.dec -d mydata.gpg
-o output.enc
表示将加密后文件输出到output.enc文件中,如果省略该项,默认将解密后的数据打印到命令行(也可以使用
> file
来指定文件)。
-e
指定解密的文件名,经测试该项必须放于最后。
如果您有多个密钥,它将选择正确的一个,如果不存在正确的密钥,则报错。
签名文件
有三种签名方式
注:以下三种方法都可以用参数
--local-user UserID
或
-u UserID
来指定使用哪个用户来签名,适用于你的电脑中有多个用户的情况,前提是你有那个用户的私钥(废话)
- –detach-sign 或 -b
gpg -o file.asc -b data
-b
表示单独生成签名文件
-o
指定输出文件,缺省为输出到data.asc中
特点:单独生成签名文件,可以保证原文件的完整性。常用于二进制文件等较大的文件。
验证方式: gpg --verify file.asc data
第一个文件为签名文件,第二个为原文件。在签名文件的名字为原文件+.asc时gpg会自动寻找原文件,即gpg --verify testVIdeo.asc会自动将文件testVIdeo作为原文件(如果存在)进行验证。注:不用考虑其他文件顶替的可能性,gpg程序会检测是不是分离签名
- –clearsign
gpg -o file --clearsign data
-o
指定输出文件,缺省为在命令行打印
--clearsign
在原文件保持明文的基础上加入签名
特点:此选项用于 ASCII(文本)数据
验证方式: gpg --verify test 或 gpg -d test (推荐前者,会检测是不是分离签名)
另: gpg -o output -d test 可以将签名中的数据单独提取到 output 文件中
- –sign (很少单独使用)
此选项最常与加密一起使用(
--encrypt
);但是它可以单独使用(这种情况很少见)
特点:不存在明文(但是实际上没有加密),可以使用
--verify
验证签名,但是看不到明文。使用
gpg -d
时能看到明文与签名。很少单独使用,常见用法见下一项。
签名并加密文件
gpg -r User1 -r User2 -s -o data.enc -e data
以User1,User2为接收者,签名并加密文件data,输出加密后的文件到data.enc中
相关参数请翻看加密与签名相关内容
修改/吊销密钥相关
修改密钥相关数据
gpg --edit-key [USERID]
进入交互式窗口,输入help获取帮助
以下为常用指令:
- passwd 修改密码
- uid 选择用户标识 N(可以使用索引和ID)
- key 选择子密钥 N(可以使用索引和ID)
- expire 变更密钥或所选子密钥的使用期限
- primary 标记所选的用户标识为主要
- trust 修改对该密钥的信任程度(会立即更新信任数据库,无需保存)
- delkey 删除选定的子密钥
- revsig 吊销所选用户标识上的签名
- revuid 吊销选定的用户标识
- revkey 吊销密钥或选定的子密钥
- save 保存并退出
- quit 退出交互式终端
使用交互终端吊销
进入交互式窗口,使用
list
查看需要吊销的子密钥ID,使用
key ID
选中子密钥(或者使用索引),被选中的子密钥ssb后会有
*
号,输入
revkey
吊销选定的子密钥,如果公钥上传到了服务器上,在本地吊销后还需使用 gpg --send-keys [USER_NAME] 发布吊销信息。
使用吊销证书吊销
- gpg --gen-revoke USER_NAME > revoke
生成 USER_NAME 的吊销证书,输出到revoke文件中
- gpg --import revoke
从本地文件 revoke 导入吊销证书,此时本地对应的密钥已经是吊销状态
- gpg --send-keys [USER_NAME]
如果之前已经发布到密钥服务器上,需要发布吊销信息
子密钥相关
生成子密钥
- gpg --expert --edit-key UserID
--expert
可以启用更多调整选项,可以不启用
使用
--edit-key
编辑已经生成好的主密钥,进入
gpg
提示符模式
- 输入 addkey,添加子密钥
这里选择椭圆曲线加密算法,先创建用于签名的,即选10,之后会提示选择用于签发密钥的椭圆曲线。
其中美国国家标准与技术研究院(NIST)系列椭圆曲线、Brainpool系列椭圆曲线、secp256k1都存在不同的安全风险,不予考虑。尤其是NIST与NSA说不清道不明的关系,可能是故意留下的弱化实现。
25519椭圆曲线是最快的椭圆曲线之一,而且没有专利壁垒,是公有领域的产品,在2013年NSA的Dual_EC_DRBG后门爆出之后备受关注。目前,25519曲线作为P-256的成功替代者,被众多应用广泛使用,支持良好。
本教程中的子密钥都选择了“Curve 25519”。
然后是设置过期时间,子密钥过期时间可以较短,这里设置为3年,之后的确认,输入密码即可。
同理创建分别用于E,S,A的三个子密钥,save保存并退出
子密钥的备份
gpg -a --export-secret-subkeys [UserID] > subkeys
备份所有子密钥到文件subkeys
子密钥的导入
此部分与普通密钥相同,使用
--imporrt
子密钥的删除
此部分与普通密钥相同,使用
--delete-keys ID
如果
gpg -K
看不到子密钥ID,可使用
gpg -K --keyid-format short
子密钥的吊销
与密钥吊销部分相同,使用
--edit-key UserID
进入终端来吊销,参看
使用交互终端吊销
章节。
注:GPG 不允许用户生成子密钥的吊销证书,而是把变更都放在唯一的公钥中,简洁且不易出错。你只需要编辑主公钥,将子密钥单独吊销,然后重新发布公钥即可,这样大家就都知道了。
GPG的一些问题
gpg --list-keys 或 gpg --list-secret-keys 不显示key ID
最新版的gpg -k等指令默认不显示key ID了,需要添加一项参数
--keyid-format short
,其中short可在
none|short|0xshort|long|0xlong
中选择,对应不同的key ID长度
Example:
gpg -k --keyid-format short
能否从公钥服务器删除公钥
不能,将 Key 上传至 Key Server 基本上是一个不可逆的行为(因此最好不要随便上传乱七八糟 Key),即使你吊销了 Key 或者 Key 过期了, Key Server 会将该 Key 标记为已吊销或者已过期,但不会删除。 因为 Key Server 之间是同步的,一旦你将 Key 传到一个 Key Server 上之后,该 Key 不久便会被同步到世界各地的 Key Server 上去。基本上就不可删除了。
当子密钥和主密钥的功能重叠时,会使用哪个?
笔者实测在签名时会自动使用子密钥。
GPG常规安全流程
基本思想:主私钥只保留签名功能,平时离线保存不使用,仅使用子密钥,若子密钥泄露则单独吊销子密钥。
- 创建主密钥对
gpg --full-gen-key --expert
使用完全版密钥生成,并启用更多参数调整。取消主密钥SAE功能,仅保留C功能,使用时间可以是永久。
- 创建子私钥
可使用ECC算法+Curve 25519曲线,分别创建S,A,E功能的子私钥,使用时间几年即可
- 导出所有子私钥subkeys,所有私钥allkeys,吊销证书revoke三个文件(不用公钥)
使用智能卡或U盘等离线备份allkeys,revoke文件,原文件记得删
- 删除所有私钥(不删公钥)
- 导入子私钥文件subkeys
若再次用
-K
参数列出私钥,可以看到主密钥私钥一行
sec
后有了一个
#
字符,这说明在本设备上缺失主密钥的私钥,也即成功离线备份了主密钥的私钥。
- 发布公钥 上传公钥到服务器
版权归原作者 Saniter_ 所有, 如有侵权,请联系我们删除。