2 个版本

0.2.1 2024年8月8日
0.2.0 2024年1月27日
0.1.0 2024年1月14日

网络编程 中排名第 1095

Download history 2/week @ 2024-05-19 13/week @ 2024-06-30 4/week @ 2024-07-28 138/week @ 2024-08-04 254/week @ 2024-08-11

每月下载量 396
用于 morf-mqtt-bridge

Apache-2.0 许可证

19KB
331

MoRF

MoRF 是一种在具有小 MTU 的有损数据包链路上的相互认证加密通信协议,例如 LoRa。受 Noise 启发。

  • no_std 兼容,不进行动态内存分配
  • 最小支持的 MTU:49 字节,数据包开销:19 字节
  • 原语:X25519 + BLAKE3 + ChaCha20-Poly1305
  • 隐藏身份,前向保密,重放保护

握手

为了建立加密会话,客户端向服务器发起握手以交换密钥。双方都需要事先了解彼此的公钥。

符号表示法

  • $CE_{pub}$, $CE_{sec}$: 客户端临时 X25519 公钥/私钥
  • $SE_{pub}$, $SE_{sec}$: 服务器临时 X25519 公钥/私钥
  • $CS_{pub}$, $CS_{sec}$: 客户端静态 X25519 公钥/私钥
  • $SS_{pub}$, $SS_{sec}$: 服务器静态 X25519 公钥/私钥
  • $X25519(secret, public)$: X25519 Diffie-Hellman 密钥交换
  • $ChaCha20(key, payload)$: 将从 $key$ 生成的 (未认证) ChaCha20 密钥流应用于 $payload$
  • $Mac(key, payload)$: 将 $key$ 应用于 $payload$ 的 BLAKE3 密钥哈希,并将输出截断为前 16 个字节。
  • $DeriveKey(key, info)$: 使用 BLAKE3 作为 KDF 并将 $info$ 作为信息字符串从 $key$ 提取 32 字节子密钥
  • $Hash(payload)$: 计算 $payload$ 的 BLAKE3 哈希,并将输出截断为前 16 个字节。
  • $InitialEncryptionKeyInfo$: 字符串 initial_encryption_key
  • $ServerEphemeralPublicKeyMacKeyInfo$: 字符串 server_ephemeral_public_key_mac_key

数据包 1:客户端到服务器(49 字节)

设 $InitialKey = DeriveKey(X25519(CE_{sec}, SS_{pub}), InitialEncryptionKeyInfo)$。

字段 长度
$Const(3)$ 1
$CE_{pub}$ 32
$ChaCha20(InitialKey, Hash(CS_{pub}))$ 16

数据包 2:服务器到客户端(49 字节)

根据提供的哈希值查找客户端静态公钥 $CS_{pub}$。

设 $ServerSepkMacKey = DeriveKey(X25519(SS_{sec}, CE_{pub}), ServerEphemeralPublicKeyMacKeyInfo)$。

设 $ServerSessionKey = Concat(X25519(SE_{sec}, CS_{pub}), X25519(SE_{sec}, CE_{pub}))$。

字段 长度
$Const(1)$ 1
$SE_{pub}$ 32
$Mac(ServerSepkMacKey, SE_{pub})$ 16

完成(客户端)

设 $ClientSepkMacKey = DeriveKey(X25519(CE_{sec}, SS_{pub}), ServerEphemeralPublicKeyMacKeyInfo)$。

检查

$Mac(ClientSepkMacKey, Packet2[1:33]) == Packet2[33:49]$

设 $ClientSessionKey = Concat(X25519(CS_{sec}, SE_{pub}), X25519(CE_{sec}, SE_{pub}))$。

依赖项

约4.5MB
约97K SLoC