密码学信任与 OpenPGP 详解

2026-02-18T19:57:27+08:00

在本文中,我将解释密码学信任、OpenPGP、它们如何工作以及它们为何重要。

技术背景:数学如何保卫安全与隐私

如果你不关心非对称密码学与 OpenPGP 的底层数学原理,仅希望了解如何明智地使用密码学信任,那么你只需知道以下几点:

若只需要实用指导,可以跳过本节剩余内容。

对称加密使用同一把密钥进行加密和解密。它可抵抗暴力破解,但存在实际缺点。如果 Alice 和 Bob 使用对称加密互发消息,他们必须先协商一个共享密钥,这通常需要额外的安全通道(例如当面见面)。这不便,而且共享密钥不得泄露——如果 Mallory 得到密钥,保密性就丧失了。

非对称密码学在此发挥作用。非对称方案为加密与解密使用不同的密钥,分别称为公钥和私钥。公钥可以张贴在个人网站或社交媒体上,因为公钥不足以推导出对应的私钥;私钥则由其持有者保管。

精心设计的算法用于生成公私钥对,以保证用公钥加密的数据只能由对应的私钥解密。常见算法包括 RSA、椭圆曲线密码学(ECC)等。

RSA 是一种经典的非对称算法,历史悠久。理解 RSA 有助于建立对非对称密码学的直觉。

简要地说,RSA 的密钥生成如下:Alice 随机选择两个互异素数 pq,计算 n = p * qΦ(n) = (p - 1) * (q - 1),选择一个满足 1 < e < Φ(n) 且与 Φ(n) 互质的整数 e,然后计算 e 关于 Φ(n) 的模逆并记为 d。Alice 的公钥为 (n, e),私钥为 (n, d)。Bob 对消息 m 进行加密时计算 c = (m ** e) % n 并把密文 c 发送给 Alice;Alice 用 m = (c ** d) % n 恢复原文。

有人会问:已知公钥 (n, e) 是否能算出 d?要算出 d 需要 Φ(n),而要算出 Φ(n) 则需知道 pq。要从 n 中恢复 pq,必须对 n 进行因式分解。对于常用的 RSA 密钥长度(例如 4096 位),把 n 因式分解在当前技术下计算量极大,几乎不可行。这就是 RSA 安全性的基础。

ECC 及其他非对称方案依赖不同的困难问题,但它们共享核心原则:应使从公钥推导私钥在计算上极为困难。

在实际计算 e 关于 Φ(n) 的模逆时,我们选取最小的正整数逆元,该数小于 Φ(n)。如果 g = gcd(d, Φ(n)) > 1,则会导致矛盾(因为存在整数 k 使 e * d + k * Φ(n) = 1),因此 g 必须为 1,dΦ(n) 互质。这一对称性说明 ed 在数学上具有互补性质;尽管理论上可交换,但在实践中签名与加密有不同的使用方式。

具体而言,RSA 的签名通常计算 s = m ** d % n,验证时检查 m == s ** e % n。在实际的端到端保密与认证中,发送者通常先用私钥对消息签名,再用接收者的公钥对已签名的数据加密;接收者先用自己的私钥解密,再用发送者的公钥验证签名。

什么是密码学信任以及它为何重要

全球范围内的监控和审查都影响着通信。除了一些高风险地区外,某些地区(例如欧洲)出现的“聊天监管”等政策也引发广泛关注。使用支持端到端加密的自由软件即时通信工具(如 XMPP、Matrix、SimpleX)至少可以在一定程度上保护通信。非对称密码学能让通信双方在没有预置安全通道的情况下建立安全通道:一个密钥用于加密,另一把用于解密,只有对应私钥的持有者能读取密文。

然而,还有另一个尚未解决的问题。假设 Alice 和 Bob 想安全地交换公钥以通信,但 Mallory 对中间进行拦截并替换她自己的公钥给双方。Alice 会把 Mallory 的公钥误认为是 Bob 的,而 Bob 也会把 Mallory 的公钥误认为是 Alice 的。于是 Alice 发送一条签名并加密的消息,本应只有 Bob 能得到,但实际上 Mallory 能解密、阅读甚至修改,然后用她自己的私钥重新签名并加密转发给 Bob。Bob 解密并用 Mallory 的公钥验证签名,错误地认为消息来自 Alice。如此一来,端到端加密的保密性和真实性都被 Mallory 破坏了。

要解决这个问题,Alice 需要有办法验证她所持有的公钥确实属于 Bob。这通常也需要一个安全的通信渠道(例如当面核验)。我们称 将公钥归属验证为建立密码学信任

一旦 Alice 与 Bob 之间建立了密码学信任,除非能从公钥推导出对应的私钥,否则 Mallory 很难冒充 Bob。

密码学信任的核心原则:身份一致性验证

上文情形是密码学信任建立的基本示例。你可以在身份间构建非常庞大的信任网络,但核心原则十分简单:通过验证某个身份与另一个已被信任的身份是否一致来建立对该身份的密码学信任。

在密码学中,公钥对应一个身份。这一点非常重要:记住:公钥 = 身份(在基于密钥的信任语境下)。

身份一致性的验证一般包括两步:

例如,如果 Alice 想验证某把公钥的持有者确为 Bob,她会与 Bob 当面核验该公钥的指纹。Alice 也可以要求 Bob 使用私钥对一段文本签名(例如 “I am Bob” 或者由 Alice 随机生成的挑战字符串)。通过这种方式,Alice 就在该公钥上建立了密码学信任,从而信任该公钥所代表的身份。

现在再看另一种情形:已知公钥 A 的身份是可信的(它确属 Bob),另有一个预期也属于 Bob 的公钥 B,Alice 想验证 B。由于她已信任 A,便无需再次与 Bob 当面核验。她只需验证 A 与 B 之间的一致性——通常通过双方相互签署包含对方指纹的声明来完成:

如此便可验证 A 与 B 的一致性,从而对 B 建立信任。

首先信任哪个身份?

密码学信任的建立过程依赖于一个已被信任的身份。但你刚认识的人并没有可信身份。常见做法是对首次接触的身份先盲目信任,这称为 ToFU(Trust on First Use),首次被盲目信任的身份就是 initial identity

例如,若 Alice 与 Bob 当面相识,Alice 首先信任的是“生物学上的 Bob”。若他们在 Matrix 社区首次接触,初始信任的就是 Bob 的 Matrix 账户及其公钥。若在 XMPP 上见面,Alice 可能信任 Bob 首条消息中的 OMEMO 指纹。

这是一种合理的实践:当你决定与从网络上认识的朋友见面时,通常会通过你用来认识对方的通信工具来核验对方。

常见的密码学信任实践

通过验证身份之间的一致性,Alice 构建了一张:身份为顶点,保证的一致性为。与 Bob 的初始身份相连的那个连通分量的所有顶点,都是 Bob 的受信任身份。

按照建立图的方式,有几类常见实践:

  1. 不受限的信任链/网络。 任意受信任的身份可用于通过验证一致性来建立对未受信任身份的信任,信任链/网络可以自由生长。
    优点:方便;丢失联系时更不易导致失联。
    缺点:对冒充的鲁棒性最低;从初始身份到其他身份的某些信任链可能很长;若某一身份被攻破,会连带影响很多其他身份。

  2. 以初始身份为中心。 只有初始身份能用于通过验证一致性来建立对新身份的信任。
    优点:如果初始身份可靠,信任非常稳固;从初始身份到其它身份的信任链长度均为一,整体网络更难被攻破。
    缺点:若初始身份不强或不可用,就无法建立稳固的密码学信任;单点故障问题明显。

  3. 以唯一密码学身份为中心。 初始身份先对一个唯一的密码学身份(通常为一对密钥)建立信任,此后仅用该密码学身份来对其它未信任身份进行一致性验证。这也是我的策略,我使用 OpenPGP 作为密码学解决方案。
    优点:在确保中心身份稳健与保持较短信任链之间取得较好平衡。
    缺点:仍存在单点故障:一旦中心密钥被攻破,后果严重。

基于密码学的一种常见身份验证方法:挑战-响应

若 Alice 已信任 Bob 的某把公钥,但想验证某个实体确为该私钥的持有者,可采用挑战-响应(Challenge–Response):

  1. Alice 生成一个随机字符串,称为“挑战”。
  2. Alice 将挑战发送给 Bob,Bob 使用私钥对该文本签名。
  3. Bob 将签名返回,Alice 使用公钥验证签名。

挑战在生成后不必保密,但应具有不可预测性和唯一性。若签名有效,则 Alice 成功验证对方确为私钥持有者。

关于维护密码学信任的非常重要的一点:不要泄露你的私钥!

密码学信任的安全性和鲁棒性基于私钥的安全与保密。泄露私钥就等于泄露信任。

因此,尽量不要泄露你的私钥!一旦私钥被泄露,他人对你的信任 将不再有效

尤其是使用 OpenPGP 管理信任的人,请务必将你的 OpenPGP 私钥保密至最高级别! 将私钥存放在硬件令牌上(例如 Nitrokey、CanoKey 或 YubiKey)是良好做法;如果不能,则至少将私钥保存在运行 100% 自由软件的设备上。

OpenPGP 及其自由软件实现

OpenPGP 不是某个软件,而是一项标准。它定义了一种将若干原始密钥对封装并组织在一起的格式,便于用于加密、签名、认证等。OpenPGP 支持 RSA、ECC 与其它算法。

以 GnuPG 为例说明如何使用 OpenPGP:

  1. 生成密钥:运行 gpg --full-generate-key 并按提示操作。
  2. 加密:运行 gpg --encrypt。可将要加密的内容通过标准输入传入(若为文件可用 cat <filename> | gpg --encrypt)。生成的密文将输出到标准输出,默认是二进制,建议用重定向保存为文件。若需文本形式的加密结果,请使用 gpg --encrypt --armor
  3. 文本签名:运行 gpg --clear-sign,将要签名的文本通过标准输入输入,完成后按 Ctrl+D。签名的文本将输出到标准输出。
  4. 解密/验证:运行 gpg --decrypt,将加密或签名的数据通过标准输入提供。解密后的数据输出到标准输出,验证结果会输出到标准错误。

在 GNU/Linux、*BSD、Windows 和 macOS 上,最常用的实现是 GnuPG,其图形前端有 Kleopatra。Android 上较为流行的是 OpenKeychain。

详细使用指南超出本文范围,请查阅相关文档与检索资料。FSF 的 Email Self-Defense Guide 是一个不错的起点;欲深入学习可参考 GnuPG 官方手册、FSFE 的 OpenPGP 指南与 KDE 的入门文档。

如何用 OpenPGP 加密电子邮件

自由软件的邮件客户端(例如 Thunderbird)内建 OpenPGP 支持,可以无缝地对邮件进行加密、解密与签名验证。像 Mailvelope 这样的浏览器扩展可以将 OpenPGP 集成到 webmail 中,使在 webmail 服务上使用加密邮件更为便捷。

请查阅对应工具的文档以了解具体操作方法。

如何用 OpenPGP 建立密码学信任

使用 OpenPGP 建立信任思路很简单:

  1. 索要对方的 OpenPGP 公钥。
  2. 验证该密钥与对方的初始身份是否一致;从而在该公钥上建立信任。
  3. 未来在验证对方其他身份时,校验这些身份与该 OpenPGP 公钥的一致性。

结语:拥抱自由软件,并明智使用

多亏自由软件社区,我们已拥有许多稳健工具。学会使用这些工具,我们便拥有能力来捍卫安全、隐私与数字权利,保护自己免受各种威胁、监控与审查。

Tildeverse Banner Exchange