matthiaskonrath/PQC-WireGuard

GitHub: matthiaskonrath/PQC-WireGuard

基于 Go 的后量子增强型 WireGuard 实现,采用 NIST 标准化的 ML-KEM-768 混合密钥交换和 ML-DSA-65 身份认证,为 VPN 隧道提供抵御量子计算威胁的加密通信能力。

Stars: 0 | Forks: 0

# PQC-WireGuard 基于 Go 语言实现的后量子增强型 WireGuard。 PQC-WireGuard 使用混合后量子密钥交换 (ML-KEM-768) 和可选的后量子身份验证 (ML-DSA-65) 扩展了 WireGuard 协议,同时保持与标准 WireGuard 的完全向后兼容性。 ## 工作原理 ### 架构 PQC-WireGuard 将 [wireguard-go](https://git.zx2c4.com/wireguard-go) 作为库嵌入,并在单个进程中与其一起运行 PQC sidecar。该 sidecar 执行后量子密钥交换,并将生成的秘密注入到 WireGuard 的预共享密钥字段中。 ``` ┌─────────────────────────────────────────────────────────┐ │ pqc-wg (single binary) │ │ │ │ ┌───────────────────┐ ┌───────────────────────┐ │ │ │ wireguard-go │ │ PQC Sidecar │ │ │ │ (embedded) │ UAPI │ │ │ │ │ │◄──────┤ ML-KEM-768 exchange │ │ │ │ TUN device │ PSK │ ML-DSA-65 auth │ │ │ │ UDP transport │ set │ 120s rekey cycle │ │ │ │ Noise handshake │ │ │ │ │ │ Packet routing │ │ UDP :ListenPort+1 │ │ │ └─────────┬─────────┘ └───────────┬───────────┘ │ │ │ │ │ └────────────┼─────────────────────────────┼──────────────┘ │ │ ┌───────▼───────┐ ┌────────▼────────┐ │ UDP :51820 │ │ UDP :51821 │ │ WireGuard │ │ PQC handshake │ │ tunnel data │ │ key exchange │ └───────────────┘ └─────────────────┘ ``` ### 握手模式 | 模式 | 配置 | 类型 | 算法 | 兼容性 | |------|--------|-------|------------|---------------| | Legacy | `pqc=off` | 1/2 | X25519 | 标准 WireGuard | | Hybrid KEM | `pqc=required` | 5/6 | X25519 + ML-KEM-768 | 仅限 PQC-WireGuard 对等点 | | Full PQC | `pqc_auth=required` | 7/8 | X25519 + ML-KEM-768 + ML-DSA-65 | 仅限 PQC-WireGuard 对等点 | ### PQC 密钥交换流程 (Hybrid KEM) ``` Initiator (Client) Responder (Server) ────────────────── ────────────────── 1. Generate ephemeral X25519 keypair Generate ephemeral ML-KEM-768 keypair ── Type 5: Initiation ──────────────► │ X25519 ephemeral public key │ ML-KEM-768 ephemeral public key │ Encrypted static key │ Encrypted timestamp 2. Verify initiation DH(static, ephemeral) KEM encapsulate against initiator's ML-KEM PK ◄── Type 6: Response ─────────────── │ X25519 ephemeral public key │ ML-KEM-768 ciphertext │ Encrypted empty payload 3. DH(ephemeral, ephemeral) KEM decapsulate using ephemeral ML-KEM SK 4. DH(ephemeral, ephemeral) ┌────────── Both sides derive: ───────────────┐ │ │ │ chainKey = KDF(chainKey, DH_ee) │ │ chainKey = KDF(chainKey, KEM_shared_secret)│ │ chainKey = KDF(chainKey, DH_se) │ │ chainKey = KDF(chainKey, PSK) │ │ │ │ sessionKey = KDF(chainKey) │ │ │ └──── Inject as WireGuard PSK via UAPI ───────┘ │ ▼ WireGuard handshake completes using the PQC-derived PSK │ ▼ Encrypted tunnel traffic (ChaCha20-Poly1305, unchanged) ``` ### 混合密钥推导 混合方法确保仅破解经典或后量子密码术不会危及会话安全: ``` X25519 DH(ephemeral, ephemeral) ML-KEM-768 Encapsulate │ │ ▼ ▼ DH shared secret KEM shared secret (32 bytes) (32 bytes) │ │ └──────────┐ ┌────────────────────┘ ▼ ▼ ┌─────────────┐ │ HKDF-BLAKE2s│ │ (KDF chain) │ └──────┬──────┘ │ ┌────────────┼────────────┐ ▼ ▼ ▼ DH(static, PSK mixing Session key ephemeral) derivation │ │ │ └────────────┴────────────┘ │ Combined session keys (send/recv) Security guarantee: ┌─────────────────────────────────────────────┐ │ If X25519 broken → ML-KEM still protects │ │ If ML-KEM broken → X25519 still protects │ │ Both must be broken to compromise session │ └─────────────────────────────────────────────┘ ``` ### 策略决策树 ``` Peer config │ ├── pqc = off, pqc_auth = off │ └── Standard WireGuard (types 1/2) │ Full legacy compatibility │ ├── pqc = opportunistic, pqc_auth = off │ └── Try PQC (type 5), fall back to │ classical (type 1) if peer rejects │ ├── pqc = required, pqc_auth = off │ └── Hybrid KEM required (types 5/6) │ Quantum-safe confidentiality │ Classical authentication │ ├── pqc = required, pqc_auth = required │ └── Full PQC (types 7/8) │ Quantum-safe confidentiality │ Quantum-safe authentication │ Requires ML-DSA-65 keys │ └── pqc = off, pqc_auth = required └── INVALID — rejected at startup ``` ## 构建 ### 要求 - Go 1.21 或更高版本 ### 编译 ``` # 为当前平台构建 go build -o pqc-wg . # 交叉编译 GOOS=linux GOARCH=amd64 go build -o pqc-wg-linux-amd64 . GOOS=linux GOARCH=arm64 go build -o pqc-wg-linux-arm64 . GOOS=darwin GOARCH=arm64 go build -o pqc-wg-darwin-arm64 . GOOS=darwin GOARCH=amd64 go build -o pqc-wg-darwin-amd64 . GOOS=windows GOARCH=amd64 go build -o pqc-wg-windows-amd64.exe . ``` 单个静态二进制文件,无外部依赖。所有密码学均为通过 [Cloudflare CIRCL](https://github.com/cloudflare/circl) 实现的纯 Go 语言——无需 CGo、liboqs 或系统库。 ### 运行测试 ``` go test ./... -v ``` ### 运行基准测试 ``` go test ./... -bench=. ``` ## 平台支持 | 平台 | 架构 | 状态 | |----------|-------------|--------| | macOS | arm64 (Apple Silicon) | 支持 | | macOS | amd64 (Intel) | 支持 | | Linux | amd64 | 支持 | | Linux | arm64 | 支持 | | Windows | amd64 | 支持 | ## 使用方法 ### 启动隧道 ``` # 在前台启动(Ctrl-C 停止) sudo pqc-wg up wg0 --config /path/to/config.conf # 作为 daemon 启动(后台) sudo pqc-wg up wg0 --config /path/to/config.conf --daemon # 附带详细日志 sudo LOG_LEVEL=verbose pqc-wg up wg0 --config /path/to/config.conf # 停止运行中的 tunnel sudo pqc-wg down wg0 # 显示 tunnel 状态 sudo pqc-wg show wg0 ``` ### Systemd (Linux) ``` # 安装 sudo cp pqc-wg /usr/local/bin/ sudo cp dist/pqc-wg@.service /etc/systemd/system/ sudo mkdir -p /etc/pqc-wg sudo cp wg0.conf /etc/pqc-wg/wg0.conf # 启用并启动 sudo systemctl enable --now pqc-wg@wg0 ``` ### 生成密钥 ``` # 生成 X25519 keypair(以 config 格式输出 PrivateKey 和 PublicKey) pqc-wg genkey # 从 private key 推导 public key(自动检测 X25519 或 ML-DSA-65) echo "" | pqc-wg pubkey # 生成 ML-DSA-65 认证 keypair(用于 pqc_auth=required 模式) pqc-wg genkey --pqc-auth ``` ### 其他命令 ``` pqc-wg validate myconfig.conf # Validate a configuration file pqc-wg show-config myconfig.conf # Show parsed config (secrets redacted) pqc-wg info # Show PQC algorithm information ``` ## 配置 PQC-WireGuard 使用带有 PQC 扩展的标准 WireGuard INI 配置格式。 ### Hybrid KEM(推荐起点) ``` [Interface] PrivateKey = Address = 10.0.0.1/24 ListenPort = 51820 PQCDefaultPolicy = required [Peer] PublicKey = AllowedIPs = 10.0.0.2/32 Endpoint = 203.0.113.2:51820 ``` ### Full PQC(最大抗量子性) ``` [Interface] PrivateKey = Address = 10.0.0.1/24 ListenPort = 51820 PQCDefaultPolicy = required PQCAuthDefaultPolicy = required PQCAuthPrivateKey = [Peer] PublicKey = AllowedIPs = 10.0.0.2/32 Endpoint = 203.0.113.2:51820 PQCAuth = required PQCAuthPublicKey = ``` ### Legacy 模式(标准 WireGuard 兼容性) ``` [Interface] PrivateKey = ListenPort = 51820 PQCDefaultPolicy = off [Peer] PublicKey = AllowedIPs = 10.0.0.2/32 Endpoint = 203.0.113.2:51820 ``` ### 配置参考 #### 接口 (Interface) 部分 | 键 | 值 | 默认值 | 描述 | |-----|--------|---------|-------------| | `PrivateKey` | base64 | (必需) | X25519 私钥 | | `Address` | CIDR | | 隧道地址 | | `ListenPort` | 0-65535 | | UDP 监听端口 | | `DNS` | IP 列表 | | DNS 服务器(逗号分隔) | | `MTU` | 576-65535 | 1420 | 隧道 MTU | | `PostUp` | 命令 | | 接口启动后运行的 Shell 命令(`%i` = 接口) | | `PostDown` | 命令 | | 接口关闭后运行的 Shell 命令(`%i` = 接口) | | `PQCDefaultPolicy` | `off`、`opportunistic`、`required` | `required` | 对等点的默认 PQC KEM 策略 | | `PQCAuthDefaultPolicy` | `off`、`required` | `off` | 对等点的默认 PQC 身份验证策略 | | `PQCSidecarPort` | 0-65535 | ListenPort+1 | 用于 PQC 密钥交换的 UDP 端口 | | `PQCAuthPrivateKey` | base64 | | ML-DSA-65 私钥(用于 pqc_auth) | | `PQCAuthPublicKey` | base64 | (自动派生) | ML-DSA-65 公钥 —— 如省略则从私钥自动派生 | #### 对等点 (Peer) 部分 | 键 | 值 | 默认值 | 描述 | |-----|--------|---------|-------------| | `PublicKey` | base64 | (必需) | 对等点的 X25519 公钥 | | `PresharedKey` | base64 | | 可选预共享密钥(附加熵) | | `Endpoint` | host:port | | 对等点的端点 | | `AllowedIPs` | CIDR 列表 | | 允许的 IP 范围 | | `PQCPolicy` | `off`、`opportunistic`、`required` | (来自默认值) | 此对等点的 PQC KEM 策略 | | `PQCAuth` | `off`、`required` | (来自默认值) | 此对等点的 PQC 身份验证 | | `PQCAuthPublicKey` | base64 | | 对等点的 ML-DSA-65 公钥 | | `PersistentKeepalive` | 秒 | | Keepalive 间隔 | ## 密码算法 ### 经典(与 WireGuard 保持不变) - **密钥交换**: X25519 (Curve25519) - **AEAD**: ChaCha20-Poly1305 - **哈希**: BLAKE2s ### 后量子 KEM (FIPS 203) - **算法**: ML-KEM-768(原 Kyber-768) - **安全级别**: NIST Level 3(约等于 192 位经典安全性) - **公钥**: 1184 字节 - **密文**: 1088 字节 - **共享密钥**: 32 字节 - **密钥生命周期**: 临时(每次握手重新生成) ### 后量子身份验证 (FIPS 204) - **算法**: ML-DSA-65(原 Dilithium-3) - **安全级别**: NIST Level 3(约等于 192 位经典安全性) - **公钥**: 1952 字节 - **签名**: 3309 字节 - **密钥生命周期**: 长期身份(通过带外交换) ## 项目结构 ``` pqc-wg/ ├── main.go # CLI entrypoint (up, down, genkey, validate, info) ├── pqc/ # Post-quantum cryptographic primitives │ ├── kem.go # ML-KEM-768 (FIPS 203) via CIRCL │ ├── sig.go # ML-DSA-65 (FIPS 204) via CIRCL │ └── hybrid.go # Hybrid secret combiner (HMAC-BLAKE2s) ├── device/ # WireGuard device and Noise protocol │ ├── noise-protocol.go # Handshake: standard, hybrid KEM, full PQC auth │ ├── noise-types.go # Key types, policy enums, message constants │ ├── noise-helpers.go # KDF, HMAC-BLAKE2s, Curve25519 helpers │ ├── device.go # Device struct and peer management │ ├── peer.go # Peer struct with PQC state │ └── receive.go # Message type dispatch and policy checks ├── config/ # Configuration parser │ └── config.go # WireGuard INI format with PQC extensions ├── tunnel/ # Tunnel runtime (embedded wireguard-go) │ ├── orchestrator.go # TUN creation, wireguard-go Device, OS interface config │ ├── sidecar.go # PQC key exchange over UDP, PSK injection │ └── uapi.go # In-process UAPI client for wireguard-go Device ├── dist/ │ └── pqc-wg@.service # Systemd unit file for Linux └── docs/ ├── PROTOCOL.md # Wire format specification ├── THREAT-MODEL.md # Security analysis └── MIGRATION.md # Migration guide from standard WireGuard ``` ## 与其他 PQC WireGuard 实现的比较 ``` PQC-WireGuard Rosenpass PQ-WireGuard OQS-WireGuard ────── ───────── ──────────── ───────────── Language Go Rust Go C (kernel) Architecture Single binary Separate daemon Forked protocol Kernel patch WireGuard mod None (embedded) None (sidecar) Forked Patched PQC KEM ML-KEM-768 Kyber-512 + Kyber-768 Various (liboqs) (FIPS 203) Classic McEliece (pre-FIPS) (pre-FIPS) PQC Auth ML-DSA-65 None Research None (FIPS 204) Standards NIST FIPS Pre-standard Pre-standard Pre-standard finalized algorithms algorithms algorithms Legacy compat Yes (pqc=off) Yes (alongside) No No Cross-platform Linux/macOS/ Linux/macOS Linux Linux only Windows Formal verify No ProVerif No No (peer-reviewed) Production ready No (experimental) Yes No (research) No (research) ``` **PQC-WireGuard 的独特之处:** - **FIPS 标准化算法** —— 使用最终的 NIST 标准 (ML-KEM-768 FIPS 203、ML-DSA-65 FIPS 204),而不是与最终规范不同的标准化前草案 - **可选的 PQC 身份验证** —— 唯一提供基于 ML-DSA-65 签名的身份验证(类型 7/8)的实现。其他实现仅保护机密性 —— 恢复了 X25519 密钥的量子攻击者仍然可以冒充对等点 - **单一二进制文件** —— 将 wireguard-go 作为库嵌入。无需安装或协调外部依赖 - **三层策略模型** —— 每个对等点支持 `pqc=off` / `pqc=required` / `pqc_auth=required`,允许在迁移期间进行混合部署 - **纯 Go,无 CGo** —— 使用 Cloudflare CIRCL(生产级,用于 Cloudflare 的 TLS 栈中)。不依赖 liboqs(仅标记为研究用途) **Rosenpass 的优势:** - 使用 ProVerif 进行了经过同行评审的形式化验证 - 拥有生产环境部署经验 - 在 Kyber 之外使用 Classic McEliece(基于编码的,非常保守)进行身份验证 - 较低的 ProVerif 验证成本(没有 DH 方程 —— 而是使用两个 KEM) ## 安全性 有关完整的安全分析,请参阅 [docs/THREAT-MODEL.md](docs/THREAT-MODEL.md)。 **关键属性**: - **混合保证**:仅攻破 X25519 或 ML-KEM 之一不会破坏会话机密性 - **前向保密**:所有 ML-KEM 密钥对都是临时的;泄露长期密钥不会暴露过去的会话 - **协议隔离**:每种握手模式使用不同的 Noise 协议标识符,防止跨协议攻击 - **转录绑定**:KEM 密文和 ML-DSA 签名被混合到握手转录哈希中 - **防 TOFU**:PQC 身份验证需要预先配置的对等点公钥;未知密钥将被拒绝 ## 迁移 有关从标准 WireGuard 迁移的分步指南,请参阅 [docs/MIGRATION.md](docs/MIGRATION.md)。 ## 许可证 [MIT](LICENSE) —— 有关第三方声明,请参阅 LICENSE 文件(wireguard-go MIT,CIRCL BSD-3-Clause,Go stdlib BSD-3-Clause)。
标签:EVTX分析, Go语言, ML-DSA-65, ML-KEM-768, VPN, WireGuard, X25519, 加密通信, 单文件部署, 后量子密码学, 安全协议, 抗量子计算, 数据传输安全, 日志审计, 本体建模, 混合密钥交换, 点对点加密, 程序破解, 网络安全, 网络安全, 网络隧道, 隐私保护, 隐私保护, 零依赖