GPG 101
This article is translated from my blog, feel free refer to it for the latest revisions: gpg-101
GnuPG是对由RFC4880定义的OpenPGP标准(也称为PGP)的完整且免费的实现。GnuPG允许你对你的数据和通信进行加密和签名;它具有多功能的密钥管理系统,以及用于各种公钥目录的访问模块。GnuPG,也被称为GPG,是一个命令行工具,其功能便于与其他应用程序集成。
在本文中,我将介绍GPG的基本用法。
什么是GPG?
说到GPG,你首先应该了解PGP。PGP是一种提供加密和数字签名服务的协议(Pretty Good Privacy,优良保密协议)。GPG是PGP协议的实现。PGP可以支持多种加密算法,如AES、RSA、ECC等。
你可以将它添加到你的Github中,使你对仓库的每次提交都有签名。
不要向“公钥服务器”上传任何信息,这不安全!不要进行任何与“公钥服务器”相关的操作!在本文中,我不会提及任何与“公钥服务器”相关的操作!“公钥服务器”是一种集中式服务,即使你已经撤销了公钥,它也不会删除任何信息。
一些缩写
用途
A => 身份验证(例如ssh)
C => 认证(只有主密钥具有此功能)
E => 加密
S => 签名(例如对提交进行签名)
? => 未知功能
类型
sec => 主私钥
ssb => 子私钥
pub => 主公钥
sub => 子公钥
格式
- 装甲格式:
asc
- 二进制格式:
pgp
指纹
每个密钥或子密钥都有一行由10组4个字符组成的内容。这是整个密钥的SHA-1哈希值,为160位,20字节,通常表示为40个十六进制数字。此指纹可用于唯一标识一个密钥对。
密钥ID
格式:
- 长格式:指纹的最后16个字符。
- 短格式:指纹的最后8个字符。
UID
UID即用户标识符,包含用户名、注释和电子邮件,格式为姓名 (注释) <电子邮件>
。
- 一个私钥可以有多个UID。
- UID适用于整个密钥,而不只是特定的子密钥。
- 可以轻松添加UID,但现有UID无法修改,只能撤销。
有效性
导入密钥时,其默认状态为[unknown]
(未知)。你可以检查指纹和所有者声明来验证该密钥。
信任网络
信任级别:
ultimate
(绝对信任):通常你应该只绝对信任自己的密钥。这是信任链的根。full
(完全信任):完全信任该密钥,也包括由该密钥签名的其他密钥。marginal
(边缘信任):信任该密钥,但不完全信任。如果有三个人信任该密钥,那么我也信任它。never
(从不信任):从不信任该密钥以及由该密钥签名的其他密钥。
如何使用它?
安装
brew install gpg
生成密钥
你必须快速完成以下步骤。如果过程超时,你将需要重新执行这些步骤。
gpg --full-generate-key
# 1. 然后选择密钥类型,默认选择即可。
# 2. 然后选择密钥过期时间,我选择`3y`(三年),因为你以后可以更新密钥,这样能确保你仍然可以控制该密钥。过期的密钥只是对新的加密和签名无效。但你仍然可以解密和验证现有信息,只是会被标记为已过期。
# 3. 然后输入你的姓名(UID),我不建议使用真实姓名,你可以使用用户名代替。
# 4. 然后输入你的电子邮件,确保使用在Github上已验证的电子邮件,强烈建议使用Github提供的`no-reply`(无回复)电子邮件以避免收到垃圾邮件。
# 5. 然后输入密码短语,它用于加密密钥。
# 6. 进行一些随机操作后,你的密钥就生成了。
生成子密钥
建议为密钥生成一个子密钥。并且只需使用主密钥对新的子密钥进行签名。
每个子密钥都有其自己的应用场景。
# 进入主密钥交互模式
gpg --edit-key 主密钥中的你的姓名(UID或密钥ID)
gpg > addkey
# 然后过程与前面的步骤相同。这次我选择RSA(仅用于签名)。
# 顺便说一下,在生成子密钥之前,它会要求你输入主密钥的密码短语。
# 子密钥生成后,别忘了保存密钥。
gpg > save
生成撤销证书
想象一下,如果你忘记了密钥的密码短语,或者失去了对密钥的控制,你可以使用撤销证书来撤销公钥。如果没有撤销证书,你将需要通知你的朋友你不再使用该密钥,这将是一个大问题。因此,生成撤销证书是很有必要的。
gpg --gen-revoke -ao revoke.pgp UID(或密钥ID)
# 根据你的情况进行选择
然后你将得到一个revoke.pgp
文件,你可以用它来撤销密钥。
列出密钥
gpg --list-keys # 列出公钥,你也可以使用`gpg -k`
gpg --list-secret-keys # 列出私钥,你也可以使用`gpg -K`
常用用法
# 最常用的用法! -k或-K
gpg -K --with-fingerprint --with-subkey-fingerprint --keyid-format long
此外,还有一些你可能需要使用的参数:
--with-fingerprint # 打印密钥的指纹
--with-subkey-fingerprint # 打印子密钥的指纹
--with-sig-list # 打印密钥的签名
导出密钥
gpg -ao public-key.txt --export UID(或密钥ID) # 导出公钥
# 最好在私钥前添加你的安全路径,它将直接导出到机器上。
gpg -ao secret-key --export-secret-key 主密钥ID! # 导出主私钥,记住添加`!`以导出单个密钥,否则你将导出整个私钥。
gpg -ao sign-subkey --export-secret-subkeys 子密钥ID! # 导出用于签名的子私钥。[S]
gpg -ao encrypt-subkey --export-secret-subkeys 加密密钥ID! # 导出用于加密的子私钥。[E]
最常用的情况
此外,GPG私钥通常导出为ASCII装甲版本或其Base64编码版本。
gpg --export-secret-key --armor 密钥ID > secret-key.asc
删除密钥
导出密钥后,你可以将其从机器中删除。
gpg --delete-secret-keys UID(或密钥ID) # 删除私钥
gpg --delete-keys UID(或密钥ID) # 删除公钥
如我们所知,密钥是以明文形式存储在机器中的,删除操作不会完全删除密钥,你可以使用
wipe
或其他工具来辅助删除。但仍然存在恢复密钥的风险。如果你真的想以最安全的方式生成和删除密钥,你可以尝试 Tails。
导入密钥
强烈不建议进行任何与“公钥服务器”相关的操作!
gpg --import 你的密钥文件(你的私钥或其他人的公钥)
# 输出
# `#`表示主密钥未导入,所以这是安全的。
# sec# rsa3072/密钥ID 2021-01-11 [SC]
# ...
# `#`表示子密钥已导入。
# ssb # rsa3072/密钥ID 2021-01-11 [E]
签名和验证
# 签名
# 1. 生成二进制签名文件
gpg --sign input.txt
# 2. 生成ASCII签名文件
gpg --clearsign input.txt
# 3. 分别生成签名文件和原始文件。
gpg --armor --detach-sign input.txt
# 验证
gpg --verify input.txt.asc input.txt
加密和解密
# 加密
# UID(或密钥ID)是收件人的UID或密钥ID,这意味着你必须提前导入收件人的公钥。
gpg --encrypt --recipient UID(或密钥ID) input.txt --output output.txt
# 一个简化版本
gpg -se -o encrypt.txt -r UID(或密钥ID) input.txt
# 解密
gpg --decrypt encrypt.txt --output decrypt.txt
撤销
即使你已经撤销了密钥,如果仍然有人使用过时的公钥给你发送消息,你仍然可以解密该消息,黑客也可以。导入撤销证书的操作将使整个密钥失效。已撤销的密钥只是对新的加密和签名无效。但你仍然可以解密和验证现有信息,只是它会被标记为已撤销。
想象这样一个场景,爱丽丝的私钥泄露了,她将发送一个密钥撤销证书,但由于分发不是集中式的,所以她无法确保每个人都收到了该消息。此外,密钥撤销证书需要由爱丽丝的私钥进行签名,所以如果私钥丢失,她将无法撤销该密钥。
所以一旦你撤销了密钥,你应该将已撤销的公钥推送到你通常发布密钥的地方,并通知你的朋友。
# 撤销主密钥
# 首先导入公钥
gpg --import gpg-linus.asc
# 然后导入撤销证书,这将直接使公钥失效。
gpg --import revoke
# 使用gpg -k检查密钥是否已被撤销。例如[revoked: 2024-01-01]
# 撤销子密钥
gpg --edit-key UID(或密钥ID)
# 然后选择你要撤销的子密钥
gpg > list
gpg > key 1 # 1是子密钥的索引
gpg > revoke
gpg > save
配置你的Git
- 点赞
- 收藏
- 关注作者
评论(0)