16 个版本 (9 个重大更改)
0.10.1 | 2024 年 6 月 27 日 |
---|---|
0.9.0 | 2024 年 5 月 7 日 |
0.7.1 | 2024 年 3 月 23 日 |
0.4.0 | 2023 年 12 月 22 日 |
0.1.1 | 2022 年 12 月 22 日 |
#71 in 密码学
每月 1,063 次下载
1MB
20K SLoC
Sequoia 对 GnuPG 接口的重新实现
这是一个使用 Sequoia OpenPGP 实现重新实现并替换 gpg
和 gpgv
的程序。
试试它,它是安全的!
如果您是高级用户,您现在可以尝试 Chameleon,看看它是否满足您的用例。Chameleon 不会直接修改 GnuPG 的任何数据结构,因此您可以安全地与现有的 GnuPG 安装和密钥一起尝试它。
Chameleon 将以两种方式更改您的 $GNUPGHOME
-
它将在
$GNUPGHOME/pubring.cert.d
中创建一个 openpgp-cert-d 覆盖(GnuPG 将忽略此文件),除非您使用默认的$GNUPGHOME
,在这种情况下,将使用 openpgp-cert-d 的默认位置。这提供了与其他使用通用证书存储的工具的无缝集成,例如 Sequoia 的本地 sq 前端。 -
如果您创建或导入私钥,Chameleon 将与
gpg-agent
以 GnuPG 的方式交互,并且gpg-agent
将修改$GNUPGHOME
。
Chameleon 与 GnuPG 2.2.x 和 2.4.x 的状态和 gpg-agent
兼容。如果它发现 GnuPG 的状态小于 2.1.x(即具有 secring.gpg
),则将其转换为 2.2.x 状态,就像 GnuPG 一样(即导入私钥到 gpg-agent
并添加标志文件)。
切换到 Sequoia 的 gpg-sq
要使用Chameleon,您需要安装它,然后确保它要么由您直接调用,要么由程序间接调用,而不是GnuPG。有三种方法可以实现这一点。
直接调用
如果您只通过命令行与GnuPG交互,那么用gpg-sq
代替gpg
就足够了,以便使用Chameleon而不是g10code的GnuPG。
替换 /bin/gpg
要全局替换g10code的gpg
为Chameleon,将其安装为/bin/gpg
(或/usr/bin/gpg
,或您的系统上gpg
安装的任何位置;提示:在shell中尝试type gpg
),例如使用dpkg-divert
或类似机制替换g10code的gpg
。这比使用gpg-sq
调用它更方便、更稳健,但缺点是它是全局的全有或全无开关。
使用PATH优先
如果Chameleon在您的$PATH
中可以找到gpg
之前找到g10code的gpg
,它将具有优先权。这比使用gpg-sq
调用它更方便、更稳健,同时允许更细致的替换方法(例如,如果$PATH
基于每个shell进行操作,或者基于用户如果在shell的启动文件中这样做)。
如果选择此路径,还需要确保gpgconf
指向Chameleon,因为许多程序通过gpgconf
来查找gpg
的位置,特别是那些使用GPGME的程序。为此,我们有一个可以从中构建目录使用的shim(如果您想安装Chameleon,或者您的cargo目标目录不同,您需要相应地调整它)
$ export PATH=$(pwd)/shim-release:$PATH
$ gpg --version | head -n1
gpg (GnuPG-compatible Sequoia Chameleon) 2.2.40
$ gpgconf | head -n1
gpg:OpenPGP:.../sequoia-chameleon-gnupg/shim-release/gpg
切换回g10code的gpg
您可以通过撤销上一节中讨论的替换方法在任何时候切换回使用g10code的gpg。
然而,不修改GnuPG的状态但使用覆盖层的一个后果是,使用Chameleon所做的更改不会被GnuPG获取。因此,您需要将使用Chameleon所做的所有更改同步回g10code的GnuPG。
例如,如果您使用Chameleon导入证书,它只会被插入到覆盖层中,g10code的GnuPG将看不到它。这也适用于您使用Chameleon生成密钥的情况:虽然密钥的秘密位将为人所知gpg-agent
,但公证书将不会。同样,如果您修改信任数据库,更改将只会写入我们的覆盖层。
要将证书存储和信任数据库的更改同步回,从Chameleon导出更改并将其导入到g10code的GnuPG中
$ gpg-sq --export | gpg-g10code --import
$ gpg-sq --export-ownertrust | gpg-g10code --import-ownertrust
如果您正在使用Chameleon和GnuPG并行,建议您要么使用GnuPG执行状态更改操作,要么手动或定期在cron作业中同步更改。
如何构建Chameleon
首先,您需要安装Sequoia的构建依赖项,以及SQLite3库。然后从此存储库的签出中构建Chameleon
$ git clone https://gitlab.com/sequoia-pgp/sequoia-chameleon-gnupg.git
$ cd sequoia-chameleon-gnupg
$ cargo build --release
[...]
或者,您可以更改所使用的加密库。请注意,这将改变构建依赖项。目前,支持crypto-openssl
和crypto-cng
,分别选择OpenSSL和Windows CNG。要选择不同的后端,请禁用默认功能并激活相应的功能
$ git clone https://gitlab.com/sequoia-pgp/sequoia-chameleon-gnupg.git
$ cd sequoia-chameleon-gnupg
$ cargo build --release --no-default-features --features=crypto-openssl
[...]
运行测试
要运行测试,您还需要Sequoia的命令行前端sq
。然后,您可以使用cargo
运行测试
$ cargo test
如何跟踪Chameleon的调用
如果您有一个使用GnuPG的程序,并且您想看看它是否与Chameleon兼容,一个好的方法是使用Chameleon的调试版本运行测试套件(如果没有测试套件,就按常规使用程序),并启用调用日志。日志将记录Chameleon的每次调用以及提供的所有参数,以及是否发生了错误。
$ cargo build
[...]
$ export PATH=$(pwd)/shim-debug:$PATH
$ # WARNING: this only works with a debug build!
$ export SEQUOIA_GPG_CHAMELEON_LOG_INVOCATIONS=/tmp/invocation.log
$ # Run your test suite here. This is an example:
$ (gpg --version ; gpg --lsign-key) >/dev/null 2>&1
$ cat $SEQUOIA_GPG_CHAMELEON_LOG_INVOCATIONS
814360: "gpg" "--version"
814360: success
814359: "gpg" "--lsign-key"
814359: Command aLSignKey is not implemented.
状态
gpgv-sq
gpgv-sq
功能完善。请报告您在用gpgv-sq
替换gpgv
时遇到的所有问题。gpgv-sq
是无状态的,您可以通过调用gpgv-sq
而不是gpgv
来切换到它,而无需进一步考虑。
gpg-sq
gpg-sq
功能尚未完善。它目前实现了常用命令和选项的日益增长的子集。大多数签名创建和验证命令、加密和解密命令、密钥列表命令以及一些其他命令都已实现。
目前,我们依赖GnuPG的gpg-agent
来处理密钥操作。这对于已经使用GnuPG的用户来说非常方便,但这也意味着您必须安装gpg-agent
。此外,我们没有自己的gpgconf
实现,我们依赖它来启动gpg-agent
,下游用户(如GPGME)也需要gpgconf
才能正常工作。
信任模型
Chameleon实现了GnuPG实现的信任模型的一个子集,以及一些特定于Sequoia的模型。
名称 | Chameleon | GnuPG | 描述 |
---|---|---|---|
pgp | ✓ | ✓ | 默认值,sequoia+gnupg 的别名。 |
gnupg | ✓ | ✗ | GnuPG的Web of Trust变体。 |
external | ✗ | ? | 看起来像是一个遗留下来的东西。 |
classic | ✗ | ✓ | 尚未实现。 |
direct | ✗ | ✓ | 尚未实现。 |
tofu | ✗ | ✓ | 首次使用时信任。 |
tofu+pgp | ✓ (1) | ✓ | 结合了gnupg 和tofu 。 |
auto | ✓ (2) | ✓ | 从信任数据库中读取信任模型。 |
sequoia | ✓ | ✗ | 使用cert-d中的trust-root 。 |
sequoia+gnupg | ✓ | ✗ | 结合了sequoia 和gnupg 。 |
备注
- 在Chameleon中,
tofu+pgp
是sequoia+gnupg
的别名。 - Chameleon和GnuPG在这里都默认为
pgp
,但Chameleon这意味着sequoia+gnupg
,而对于GnuPG只是gnupg
。
Sequoia
这是Sequoia管理信任根的方式。在Sequoia的信任模型中,只有证书目录中的trust-root
被用作信任根。信任通过sq pki
命令进行管理。
本模型与GnuPG的本地信任模型配合良好。这通过sequoia+gnupg
信任模型实现,这是默认设置。然而,如果您使用sq pki
来管理信任,您可以显式选择sequoia
信任模型以停用gnupg
信任模型,这稍微便宜一些,并且更容易理解。
GnuPG的Web of Trust变体
GnuPG使用所有者信任数据库来选择信任根。除了最终信任的证书外,还使用完全和边际信任的证书作为信任根,前提是它们可以被认证。
目前,我们不尊重证书链长度的限制(参数--max-cert-depth
),但将在某个时候实现。
已知的故意差异
为了提高安全性或减少重新实现中的复杂性,g10code的GnuPG的一些功能被故意没有实现。
这是一个不完整的列表。如果您注意到未在此列表中列出的差异,请提出问题,这样我们就可以与GnuPG的行为保持一致,或者将差异添加到此列表中。
相反,如果您对这里列出的差异有异议,并且有未在此处提及的、支持与GnuPG在该方面保持一致的合理论据,请也提出问题。
拒绝弱算法
我们默认拒绝比GnuPG更多的弱算法,特别是SHA-1(也请参阅本节)。
不支持短密钥ID
不支持短密钥ID,即32位密钥ID。创建具有冲突的短密钥ID是微不足道的,因此使用它们来引用密钥是不安全的。请参阅https://evil32.com 。
当在命令行参数或配置文件中使用短密钥ID时,将打印错误并使操作失败。
我们不使用dirmngr
我们不使用GnuPG的dirmngr
来连接到网络服务以发现证书。相反,我们读取其配置文件并自己执行请求。这更稳健,并提供了更多功能,例如,如果您在dirmngr.conf
中有多个keyserver
指令,我们将同时查询所有密钥服务器。
我们不使用keyboxd
我们不使用GnuPG的keyboxd
来访问keybox数据库。相反,如果我们发现一个,我们将直接从keybox数据库中读取证书。
我们拒绝--use-embedded-filename
此标志不安全,可能在解密时覆盖任意文件以包含攻击者控制的内容。我们通过使调用失败来拒绝此标志。请不要使用此标志。
无翻译,无日期和时间格式以外的本地化
GnuPG翻译所有消息和错误消息,甚至一些命令行参数(如LANGUAGE=de gpg --compression-algo unkomprimiert
...)。我们可能会在将来翻译字符串,但永远不会进行与区域设置相关的参数解析。
在GnuPG中可以通过OID指定算法
算法只能使用它们的OpenPGP算法ID和GnuPG使用的符号标识符来指定。如果您绝对需要此功能,请提出问题。
非功能性优势
与GnuPG相比,Chameleon有许多非功能性优势。
自动发现证书更新
Chameleon包含一个名为Parcimonie(以尊敬的Parcimonie)的组件,它将保持您的证书是最新的,试图以保护隐私的方式进行。
它将定期使用任何启用的自动密钥定位方法,使用随机延迟在本地证书存储中搜索更新,以尝试去相关化。如果可用,它将使用Tor。
要启用Parcimonie组件,运行gpg-sq --x-sequoia-parcimonie
,可以通过手动操作或使用服务管理器(此仓库中包含名为gpg-sq-parcimonie.service
的系统d单元文件)。
OpenPGP 兼容性
Sequoia实现了几乎所有 OpenPGP RFC4880。缺失的部分要么已经过时,要么不安全。此外,我们与IETF OpenPGP 工作组合作,并编写了一个广泛的OpenPGP 互操作性测试套件,以改善不同实现之间的互操作性。简而言之,如果您使用Sequoia加密数据,您可以确信您可以使用任何其他OpenPGP实现对其进行解密。
不再需要等待信任数据库检查
Chameleon使用非常快速的Web-of-Trust实现,我们不依赖于GnuPG之类的缓存,而是实时计算信任。这意味着对于Chameleon,gpg --check-trustdb
是无操作,而GnuPG则已知的需要很长时间。
SHA-1 缓解措施
SHA-1 已经被破解。不幸的是,SHA-1 仍然被广泛使用。为了解决这个问题,Sequoia实现了一系列的应对措施
另一方面,GnuPG接受 SHA-1,而无需任何额外的保护。
碰撞保护
Sequoia在签名和自签名中包含一个盐,以防御碰撞攻击,以及其他攻击。例如,OpenSSH 也这样做。如果其他哈希的碰撞抵抗力被破坏,这将挫败攻击者尝试执行Shambles式攻击。
多线程
得益于Rust的更安全的并发范例,Chameleon使用线程比用其他语言编写的实现更安全、更简单。Chameleon使用这一点,例如,来更快地解析密钥环。
测试方法
我们有两种测试Chameleon的方法:我们将Chameleon和GnuPG并排放置,并比较结果,我们使用使用GnuPG的程序的测试套件。
使用GnuPG作为测试预言机
我们运行实验,调用Chameleon并记录人类可读和机器可读的输出和副作用,并将其与GnuPG产生的输出进行比较。这些测试在您调用cargo test
时运行,因此需要安装GnuPG。
下游测试套件
我们使用直接或间接使用GnuPG的程序测试套件,以验证我们支持所需的功能。
运行这些测试套件时经常出现的问题是,它们可能包含加密元素,如OpenPGP证书、密钥、签名和消息。这些元素很少更新,因此它们被卡在旧的时间点上,使用旧的包格式或不安全的算法。
如果您正在维护包含测试套件中加密元素的软件包,请通过定期更新元素来提供帮助。此外,尽量减少最初检查入的元素数量。在可能的情况下,尽量在测试中生成所需的元素。
- notmuch:通过(修补已应用:https://nmbug.notmuchmail.org/nmweb/show/20220909161250.715226-1-justus%40sequoia-pgp.org)
- emacs:通过(修补已应用:https://lists.gnu.org/archive/html/bug-gnu-emacs/2022-10/msg00443.html)
- pass:通过(修补已应用:https://lists.zx2c4.com/pipermail/password-store/2022-September/004647.html)
过程中发现的错误
- gpg(v)将注释的人可读形式打印到状态-fd,https://dev.gnupg.org/T5667,已修复
- 加密时,gpg声称与不合规的gcrypt符合DE_VS规范,https://dev.gnupg.org/T6221,已修复
- gpg --faked-system-time "$(date +%s)!" 不起作用,https://dev.gnupg.org/T6222,不会修复
- GPGME不正确地解析SIG_CREATED状态行中的签名类,https://dev.gnupg.org/T6223
许可证
Sequoia GnuPG Chameleon是自由软件:您可以在自由软件基金会发布的GNU通用公共许可证的条款下重新分发它和/或修改它,许可证版本为3,或者(根据您的选择)任何较新版本。请参阅LICENSE.txt
。
Sequoia GnuPG Chameleon是GnuPG的衍生作品。它不是干净的重新实现,并且它包含GnuPG的部分,无论是直接包含,还是转录到Rust。因此,声称对GnuPG拥有版权的各方也对Chameleon的部分拥有要求权。请参阅AUTHORS.GnuPG
以获取列表。
依赖关系
~77MB
~1.5M SLoC