【WireGuard】协议原理:Noise IKpsk2、四次 DH 与 Cookie
内容提要
本文介绍WireGuard协议核心:采用Noise IKpsk2模式,通过四次DH运算实现认证、前向保密和身份隐藏。握手需1.5 RTT,首条传输包作为密钥确认。使用TAI64N时间戳防重放,Cookie机制抵御DoS攻击。会话密钥约两分钟轮换,传输数据经ChaCha20-Poly1305加密并零填充。
延伸解读
四次DH的分工与安全属性
WireGuard的握手通过四次DH运算分别实现不同安全目标:es用于加密发起方静态公钥,ss用于长期身份互证,ee提供前向保密,se则抵抗特定KCI场景。这种分工设计使得每个DH都有明确作用,而非简单重复计算。理解这一点有助于评估WireGuard在密钥泄露等极端情况下的安全性边界。
1.5 RTT的工程权衡
WireGuard采用1.5 RTT完成握手,首条传输包作为密钥确认,而非额外握手消息。这简化了UDP丢包下的状态机,但Dowling和Paterson指出,这种设计给形式化证明带来挑战。工程上的简洁性与证明模块化的摩擦,是评估其安全论证时需注意的细节。
Cookie机制与沉默原则
WireGuard的DoS防御遵循“未认证则沉默”原则:负载高时,仅对MAC1合法但MAC2无效的握手返回Cookie Reply。Cookie经AEAD保护并绑定MAC1,降低被中间人盗用或注入的风险。运维中需注意Cookie密钥每两分钟轮换,且响应方重启会丢失时间戳状态,但此时无活跃会话可被破坏。
Q&A
WireGuard 握手使用哪种 Noise 协议模式?
WireGuard 使用 Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s 模式,即 Noise IK 模式加上预共享密钥(PSK)混合。
WireGuard 握手过程中的四次 DH 运算分别有什么作用?
四次 DH 运算包括:es(DH(e_i, s_r))用于加密发起方静态公钥,ss(DH(s_i, s_r))用于双方长期身份互证,ee(DH(e_i, e_r))提供前向保密,se(DH(s_i, e_r))绑定发起方静态公钥与响应方临时密钥,抵抗某些 KCI 场景。
为什么 WireGuard 需要 1.5 RTT 才能双向发送数据?
因为 Noise IK 握手两条消息后双方已能计算会话密钥,但 WireGuard 要求发起方先发送第一条 transport 数据包作为密钥确认,响应方收到后才用新会话发送数据。这样避免了额外的确认消息,简化了状态机。
WireGuard 如何防止握手重放攻击?
WireGuard 在握手 initiation 消息中加密携带 TAI64N 时间戳,响应方对每个 peer 记录最大时间戳,拒绝时间戳不大于历史最大值的包,从而防止重放。
WireGuard 的 Cookie 机制是如何工作的?
当负载高时,响应方对 MAC1 合法但 MAC2 无效或缺失的握手返回 Cookie Reply。Cookie 是对发起方源 IP 的 MAC,密钥为响应方每两分钟轮换的 secret。发起方用 cookie 计算 MAC2 后重发握手。
WireGuard 的会话密钥多久轮换一次?
WireGuard 的会话密钥约两分钟轮换一次,具体由 REKEY_AFTER_TIME 常量控制,值为 120 秒。
WireGuard 传输数据时如何增加流量分析难度?
WireGuard 在加密前将内层 IP 包按 16 字节倍数零填充,但不修改 IP 头长度字段,从而增加流量分析难度。