GPG的使用场景简介

简介

GPG 是一个用于加解密的命令行工具,其中包含了对一些常用的加解密场景的支持命令。

GPG 是 GnuPG (GnuPrivacyGuard) 的缩写。其中的 PG 是指 PGP (Pretty Good Privacy):
https://en.wikipedia.org/wiki/Pretty_Good_Privacy

PGP 是商业用的加密软件,GPG 是自由软件基金开发的开源替代版本。

版本发布历史可参见官网 https://www.gnupg.org/

安装及入门用法

参见: https://www.ruanyifeng.com/blog/2013/07/gpg.html

MAC 环境直接 brew install gnupg

然后使用 gpg –version 确认安装成功以及查看版本信息

我当前使用版本为:

1
2
3
4
5
6
gpg (GnuPG) 2.3.2
libgcrypt 1.9.4
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

使用场景

秘钥管理

密钥管理大致包括如下几个方面:

  1. 密钥生成、查看、删除、导入、导出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 生成秘钥
gpg --full-generate-key

# 查看秘钥列表
gpg --list-keys --keyid-format long

# 删除秘钥
gpg --delete-secret-keys [Key ID]
gpg --delete-keys [Key ID]

# 添加子密钥
gpg --quick-add-key [Key ID] rsa2048 encr
gpg --quick-add-key [Key ID] rsa2048 sign
gpg --quick-add-key [Key ID] rsa2048 auth

# 导入秘钥
gpg --import private-key.txt

# 导出秘钥
# 公钥
gpg --armor --output pub-key.txt --export [Key ID]
# 私钥
gpg --armor --output private-key.txt --export-secret-keys [Key ID]
gpg --armor --output private-sub-key.txt --export-secret-subkey [Key ID]
  1. 密钥发布、搜索

密钥发布是指将自己的公钥发布到互联网上,使得别人可以搜索下载到。公钥服务器有很多,随便找一个发布就可以。公钥服务器之间会进行公钥的互相同步。

推荐使用 https://keys.openpgp.org/

搜索时可使用他人的 Key ID(邮箱或者HASH)进行搜索

1
2
3
4
5
6
7
8
9
10
# 发布公钥
gpg --keyserver hkps://keys.openpgp.org --send-keys [Key ID]
# or
gpg --export [Key ID] | curl -T - https://keys.openpgp.org
# or
# 在 https://keys.openpgp.org/upload 这里上传公钥文件

# 获取他人公钥
# 搜索 https://keys.openpgp.org/
gpg --sign-key [Key-ID]

3、密钥注销

密钥注销是指声明此密钥不可用,一般可能是由于私钥泄漏、私钥密码遗忘等原因

1
gpg --gen-revoke --output revoke.asc [Key ID]

资源发布

GPG 经常用于对资源进行签名,类似于校验码。

校验码常见的有 CRC、MD5 等,通过对资源内容做 HASH 值的计算,来确认资源内容是否被修改过。但校验码只能验证文件的完整性,是跟文件一一对应的,假如有人将文件内容和校验码同时修改了,仅使用校验码的手段是无法发现的。

GPG 的签名在校验时,可以同时确认文件完整性和签名所属用户,不同用户对同一文件的签名结果是不一样的。

举个例子:

在 Ubuntu 系统中使用 apt 命令安装软件,apt 会同时下载软件包和软件包的 GPG 签名,然后对软件包进行签名验证。

验证时会同时确认软件包的完整性和签名用户身份,只有两者都是可信的,才会信任此软件安装包并进行安装。

假如有人恶意将服务器上的软件包内容和签名都重新打包了,那么签名对应的用户信息必然会发生改变,校验时就能发现包被修改过。

完整的信任链是这样的:

  • 可信用户 -> 可信签名 -> 可信软件

之所以不简单使用如下的信任链:

  • 可信签名 -> 可信软件

是因为:

  1. 可信用户是可以枚举的,没有多少个,完全可以将可信官方的用户ID内置在系统中。

  2. 可信签名太多了,每个软件都不一样,无法枚举。

邮件加密

关于为什么要加密邮件,参见此网站:https://emailselfdefense.fsf.org/en/。

不过目前国内可能没有这个意识或者由于其他原因并不普及。

邮件加密的方式有两种:

  1. 有些邮件客户端支持GPG插件,可以自动对邮件内容进行加解密。

  2. 对于不支持的邮件客户端(国内常见的都不支持),可采用手工加密,然后将加密后的数据写进邮件发送的方式。

在 Git 中使用 GPG

Git 默认使用邮件地址来确认提交者身份,但邮件地址是可以随便修改的,假如别人使用你的邮件地址做了一个提交,那么 Git 是无法识别提交的真正用户的。

参考 https://zhuanlan.zhihu.com/p/76861431

为了防止提交被假冒,Git 引入了 GPG 签名机制。

基本原理如下:

  1. 用户将自己的 GPG 公钥上传到 Git 服务器

  2. 用户在 Commit 时使用私钥对 Commit 进行签名

  3. Git 服务器接收到 Commit 信息后,使用用户的公钥对签名进行校验,校验通过则标识为有效 Commit

邮件地址可以被伪造,但签名无法被伪造,伪造者使用伪造者的私钥进行的签名不会被 Git 服务器校验通过,因为公钥不匹配。

加解密

基本流程:

  1. 使用收件用户的公钥加密文件

  2. 将加密后的文件发送为收件人

  3. 收件人使用自己的私钥解密文件

加密

1
gpg --recipient [Key ID] --output a.encrypt.txt --encrypt a.txt

解密

1
gpg --recipient [Key ID] --output a.decrypt.txt --decrypt a.encrypt.txt

签名

基本流程

  1. 使用自己的私钥对某个文件进行签名
  2. 将签名后的文件发送给收件人
  3. 收件人使用发送者公钥验证签名

签名

1
2
3
4
5
6
# 会将文件内容和签名信息合并然后生成新的 ascii 文件
gpg --clearsign a.txt
# 同上 但生成的是二进制文件
gpg --sign a.txt
# 生成独立的签名文件
gpg --detach-sign --armor a.txt

验证签名

1
gpg --verify a.txt.asc

总结一下

GPG 最重要的作用就是在加密的同时添加了加密人的信息,使得信任机制变得更有效。

参考文档

GPG 入门教程

&ensp;&ensp;https://www.ruanyifeng.com/blog/2013/07/gpg.html

简明 GPG 概念

&ensp;&ensp;https://zhuanlan.zhihu.com/p/137801979

在 Github 上使用 GPG 的全过程

&ensp;&ensp;https://zhuanlan.zhihu.com/p/76861431

震惊!竟然有人在 GitHub 上冒充我的身份

&ensp;&ensp;https://blog.spencerwoo.com/2020/08/wait-this-is-not-my-commit