X3DH (Extended Triple Diffie-Hellman) 协议是 Signal Protocol 的一个核心组件,由 Open Whisper Systems(现为 Signal Foundation 和 Signal Messenger LLC)设计。它是一种异步密钥协商协议,旨在在两个用户之间建立一个安全的、经过认证的共享密钥,即使一方或双方不在线也能完成。X3DH 巧妙地结合了长期身份密钥、中期签名预密钥和短期一次性预密钥,以提供强大的前向保密性 (Forward Secrecy)未来保密性 (Future Secrecy),同时能够抵抗中间人攻击和密钥妥协。

核心思想:X3DH 解决了在异步通信环境中首次建立安全端到端加密会话的关键挑战。它通过使用不同生命周期的密钥(身份、签名预密钥、一次性预密钥)进行多次 Diffie-Hellman 交换,确保了即使在一方不在线的情况下,也能安全地协商出一个共享的初始根密钥,并提供双方身份的认证。


一、背景与动机

传统的 Diffie-Hellman (DH) 密钥交换协议需要在通信双方同时在线才能进行。然而,在现代即时通讯应用中,用户通常希望在联系人离线时也能发送消息,并且收到消息后能立即解密。为了解决异步通信中的密钥协商问题并提供增强的安全特性,Signal Protocol 引入了 X3DH 协议。

X3DH 的主要目标是:

  1. 异步协商:允许一个用户(Alice)在另一个用户(Bob)离线时也能发起加密会话。
  2. 身份认证:确保 Alice 知道她正在与 Bob 通信,而不是冒充 Bob 的攻击者。
  3. 前向保密性 (Forward Secrecy):即使长期私钥被泄露,过去通过该协议协商的会话密钥也能保持安全。
  4. 未来保密性 (Future Secrecy):一旦会话开始,即使当前会话密钥被泄露,但后续的 DH 交换(通过双棘轮算法)能够重新建立安全,使未来的消息依然安全。
  5. 抵抗中间人攻击 (Man-in-the-Middle, MitM):提供机制让双方能够验证对方的身份密钥,从而防止 MitM 攻击。

二、X3DH 的密钥类型

X3DH 协议使用了不同生命周期和用途的椭圆曲线 Diffie-Hellman (ECDH) 密钥对。每个密钥对由一个私钥 (sk) 和一个公钥 (pk) 组成。

  1. 身份密钥对 (Identity Key Pair, IK)

    • 生命周期:长期(用户账户的整个生命周期)。
    • 用途:作为用户的长期身份标识,用于签名和验证其他密钥,是身份认证的根基。
    • 特点:每个用户只有一对。公钥 (IK_pub) 会被上传到服务器,私钥 (IK_priv) 则严格保存在用户设备上。
  2. 签名预密钥对 (Signed Pre-key Pair, SPK)

    • 生命周期:中期(例如,每周或每月更新一次)。
    • 用途:用于异步建立会话。其公钥 (SPK_pub) 连同由身份私钥 (IK_priv) 对其签名的签名 (Signature(IK_priv, SPK_pub)) 一并上传到服务器。
    • 特点:SPK_pub 的签名证明了它是对应身份密钥的所有者生成的有效密钥,防止攻击者注入伪造的 SPK。
  3. 一次性预密钥对 (One-Time Pre-key Pair, OPK)

    • 生命周期:短期,一次性使用
    • 用途:提供额外的前向保密性。用户生成大量 OPK 对,将其公钥 (OPK_pub) 上传到服务器。当一个 OPK_pub 被使用后,它会从服务器上清除。
    • 特点:不被 IK 签名。由于其一次性使用特性,即使服务器被攻击且攻击者获取了所有 OPK_pub,每个 OPK_pub 也只能被使用一次,且与接收方长期身份密钥的泄露无关。
  4. 临时密钥对 (Ephemeral Key Pair, EK)

    • 生命周期:短期,每个会话发起时生成并使用一次
    • 用途:由发起方(Alice)生成,用于每一轮 ECDH 密钥交换,以确保发送方的前向保密性
    • 特点:公钥 (EK_pub) 随首条消息一同发送给接收方 (Bob)。

三、X3DH 协议流程

假设 Alice 想要向 Bob 发送她的第一条加密消息。

3.1 预处理阶段 (Bob)

  1. 生成并上传密钥:Bob 生成其 Identity Key Pair (IK_Bob)、几个 Signed Pre-key Pairs (SPK_Bob) 和大量 One-Time Pre-key Pairs (OPK_Bob)。
  2. 签名:Bob 用 IK_Bob_priv 对每个 SPK_Bob_pub 进行签名。
  3. 上传公钥包 (Key Bundle)
    Bob 将以下信息上传到服务器:
    • IK_Bob_pub
    • SPK_Bob_pub (及其签名 Signature(IK_Bob_priv, SPK_Bob_pub))
    • OPK_Bob_pub (一个列表,供 Alice 每次选择一个,用完即焚)

3.2 会话发起阶段 (Alice)

  1. 请求 Bob 的公钥包:Alice 从服务器请求 Bob 的 Key Bundle。服务器返回 IK_Bob_pub、一个 SPK_Bob_pub(和其签名),以及一个未使用的 OPK_Bob_pub(如果存在)。一旦 OPK_Bob_pub 被返回,服务器会将其标记为已使用或删除。

  2. 验证 SPK 签名:Alice 使用 IK_Bob_pub 验证 SPK_Bob_pub 的签名。如果签名无效,她会中止协议,因为可能存在中间人攻击。

  3. 生成临时密钥 (EK_Alice):Alice 生成自己的临时密钥对 (EK_Alice)。

  4. 执行 ECDH 交换:Alice 执行四次(或三次,如果 Bob 没有 OPK)ECDH 密钥交换以计算共享秘密。这些共享秘密组合在一起,生成一个初始的共享秘密 (SK)。

    • DH1: DH(IK_Alice_priv, SPK_Bob_pub)
    • DH2: DH(EK_Alice_priv, IK_Bob_pub)
    • DH3: DH(EK_Alice_priv, SPK_Bob_pub)
    • DH4 (可选): DH(EK_Alice_priv, OPK_Bob_pub) —— 如果存在 OPK_Bob_pub,则包含此项。

    :X3DH 协议的原始论文描述的是 DH(IK_Alice, SPK_Bob),DH(EK_Alice, IK_Bob),DH(EK_Alice, SPK_Bob) 和 DH(EK_Alice, OPK_Bob) 四次交换。实际实现中,通常会将发送方的 IK 和接收方的 SPK 视为一次 DH 交换,发送方的 EK 和接收方的 IK、SPK、OPK 视为另外三次(或两次)DH 交换。所有的共享秘密会通过一个 KDF 派生出一个主秘密,作为后续双棘轮算法的初始根密钥。

  5. 计算初始根密钥:Alice 将所有 DH 派生的共享秘密通过一个密钥派生函数 (KDF) 组合起来,生成一个初始的根密钥 (Root Key, RK)。数学上通常表示为:
    $$ RK = KDF( DH(IK_Alice, SPK_Bob) | DH(EK_Alice, IK_Bob) | DH(EK_Alice, SPK_Bob) | DH(EK_Alice, OPK_Bob) ) $$
    其中 $|$ 表示字节串连接。

  6. 发送初始消息:Alice 使用这个 RK 作为初始密钥,结合双棘轮算法加密她的第一条消息。消息中包含:

    • Alice 的 IK_Alice_pub
    • Alice 的 EK_Alice_pub
    • Bob 使用的 SPK_Bob_pub (可选,用于帮助 Bob 找到正确的链)
    • Bob 使用的 OPK_Bob_pub ID (可选,用于帮助 Bob 销毁)
    • 加密后的消息
    • 附加的认证数据 (AD)

3.3 会话响应阶段 (Bob)

  1. 接收消息:Bob 收到 Alice 的第一条消息。
  2. 从消息中提取公钥:Bob 从消息中提取 IK_Alice_pub 和 EK_Alice_pub。
  3. 定位私钥:Bob 根据消息中指示的 SPK 和 OPK ID,找到自己对应的 SPK_Bob_priv 和 OPK_Bob_priv。
  4. 执行 ECDH 交换:Bob 使用自己的私钥与 Alice 的公钥,执行相同的四次(或三次)ECDH 交换,计算出和 Alice 相同的共享秘密。
    • DH1: DH(SPK_Bob_priv, IK_Alice_pub)
    • DH2: DH(IK_Bob_priv, EK_Alice_pub)
    • DH3: DH(SPK_Bob_priv, EK_Alice_pub)
    • DH4 (可选): DH(OPK_Bob_priv, EK_Alice_pub)
  5. 计算初始根密钥:Bob 也将所有 DH 派生的共享秘密通过 KDF 组合起来,计算出与 Alice 完全相同的初始根密钥 (RK)。
  6. 销毁 OPK:如果 Bob 使用了 OPK_Bob_priv,他会立即将其销毁。
  7. 开始解密:Bob 使用这个 RK 作为初始密钥,通过双棘轮算法解密 Alice 的第一条消息。

四、X3DH 的安全特性

  1. 身份认证 (Authentication)
    • Alice 通过验证 SPK_Bob_pub 的签名来确认 SPK 确实属于 Bob 的身份密钥。
    • 通过包含 IK_Alice_pub 在消息中,Bob 也能知道是谁在尝试与他通信。
    • 这有助于抵御盲目中间人攻击。
  2. 前向保密性 (Forward Secrecy)
    • 由 EK_Alice 和 OPK_Bob 的引入提供。即使攻击者在未来获取了 Bob 的长期私钥 (IK_Bob_priv) 和 SPK_Bob_priv,只要 OPK_Bob_priv 和 EK_Alice_priv 已被销毁,攻击者也无法通过这些密钥重建先前的 DH 共享秘密,从而无法解密过去的消息。
  3. 异步性
    • 通过预密钥 (SPK 和 OPK) 的机制,Alice 可以在 Bob 离线时开始加密会话。服务器扮演了临时公钥存储和分发的角色。
  4. 抵抗密钥篡改攻击
    • 由于多层 DH 交换和 KDF 的使用,即使某一个 DH 秘密或密钥被篡改,其他秘密的组合也能确保整体安全性。

五、与双棘轮算法的关系

X3DH 协议主要用于首次建立一个安全的初始根密钥。一旦这个根密钥被成功协商,它就会作为双棘轮算法的起点

  • 双棘轮算法会使用这个初始根密钥,通过其对称密钥棘轮和 DH 棘轮机制,持续地派生新的会话密钥,从而在后续的通信中提供会话的前向保密性未来保密性,即使在通信过程中发生密钥泄露也能限制其影响范围。
  • X3DH 解决了“如何开始”安全通信的问题,而双棘轮算法则解决了“如何持续”安全通信的问题。两者结合,构成了一个强大而完整的端到端加密方案。

六、总结

X3DH 协议是现代异步端到端加密通信的基石之一。它通过创新的预密钥机制和多轮 ECDH 密钥交换,在保证身份认证的同时,提供了强大的前向保密性和异步通信能力。与双棘轮算法协同工作,X3DH 确保了 Signal Protocol 及其采纳者(如 WhatsApp, Google Messages)能够为用户提供行业领先的隐私和安全保护。理解 X3DH 的工作原理对于深入掌握现代加密通信的奥秘至关重要。