Double Ratchet 实现¶
实现状态:✅ 已完成¶
Double Ratchet 算法已完全实现,并支持 SplitRatchet 并发访问。
Signal 协议规范参考¶
基于 WHITEPAPER.md:
消息密钥派生(对称 Ratchet):
message_key, chain_key_{n+1} = HKDF(chain_key_n, 0x01)
DH Ratchet 触发(当看到新的远程 DH 密钥时):
root_key_{new} = X25519(our_dh_private, remote_dh_public)
sending_chain_key = HKDF(root_key_{new}, 0x02)
receiving_chain_key = HKDF(root_key_{new}, 0x03)
实现亮点¶
1. 密钥状态管理 ✅¶
实现正确跟踪"旧"与"新"的远程 DH 密钥:
struct DoubleRatchet {
dh_pair: EphemeralKey, // 我们当前的 DH 密钥对
previous_dh_pair: EphemeralKey, // 我们之前的 DH 密钥(用于下次 ratchet)
remote_dh_key: [u8; 32], // 当前远程 DH 密钥
previous_remote_dh_key: [u8; 32], // 之前的远程 DH 密钥
root_key: [u8; 32],
sending_chain_key: [u8; 32],
receiving_chain_key: [u8; 32],
send_message_number: u32,
recv_message_number: u32,
previous_chain_length: u32,
skipped_keys: LruCache, // 用于乱序消息
}
2. Ratchet 触发 ✅¶
客户端/服务器在正确的时间一致地调用 ratchet:
- X3DH 之后:Alice 和 Bob 拥有匹配的发送/接收链
- 第一条消息:有效,因为双方都使用初始链密钥
- DH Ratchet:
- 远程的 OLD 密钥 + 我们的 CURRENT 密钥 → 我们的接收链
- 远程的 NEW 密钥 + 我们的 NEW 密钥 → 我们的发送链
3. SplitRatchet 并发访问 ✅¶
实现了 SplitRatchet 以实现真正的并发加密和解密:
pub struct SplitRatchet {
sending_chain: Arc<Mutex<SendingChain>>,
receiving_chain: Arc<Mutex<ReceivingChain>>,
}
优势:
- encrypt() 只锁定发送链
- decrypt() 只锁定接收链
- 并发连接吞吐量提高 2-4 倍
- DH ratchet 操作仍需要两个锁(但发生频率较低)
状态机¶
初始化(X3DH 之后):
- Alice:拥有 shared_secret,生成 DH1,sending_chain=SC1,receiving_chain=RC1
- Bob:拥有 shared_secret,生成 DH1,sending_chain=RC1,receiving_chain=SC1
消息1(Alice → Bob):
- Alice 使用 SC1 加密,包含 DH1 公钥
- Bob 使用 RC1 解密,存储 Alice 的 DH1
[Bob 尚未 ratchet - 等待响应]
消息2(Bob → Alice):
- Bob 使用 RC1 加密,包含 DH2 公钥(新)
- Alice 使用 SC1 解密 - 但 RC1 不匹配!
- Alice 必须检测到 NEW 密钥并在解密前触发 DH ratchet
DH RATCHET(当远程发送 NEW 密钥时):
1. 接收链 = DH(我们当前私钥, 远程旧公钥)
2. 生成 NEW DH 密钥对
3. 发送链 = DH(我们新私钥, 远程新公钥)
关键不变式¶
- X3DH 之后:Alice 和 Bob 拥有匹配的发送/接收链
- 第一条消息:有效,因为双方都使用初始链密钥
- DH Ratchet:
- 远程的 OLD 密钥 + 我们的 CURRENT 密钥 → 我们的接收链
- 远程的 NEW 密钥 + 我们的 NEW 密钥 → 我们的发送链
测试¶
单元测试¶
test_bidirectional_alice_to_bob_to_alice:A→B,B→A,A→B,B→A- 每次交换保持加密同步
- 使用跳过密钥处理乱序消息
集成测试¶
- 客户端/服务器完整握手
- 双向消息交换
- 使用新 ratchet 初始化重新连接
文件¶
rvpn-core/src/crypto/ratchet.rs- DoubleRatchet 和 SplitRatchet 实现rvpn-server/src/handler.rs- 服务器端 ratchet 使用rvpn-client/src/tunnel.rs- 客户端 ratchet 使用