djx-y-z/openmls_dart
GitHub: djx-y-z/openmls_dart
OpenMLS 的 Dart 绑定库,为 Flutter 和跨平台应用提供符合 RFC 9420 标准的可扩展端到端加密群组消息传递能力。
Stars: 9 | Forks: 4
# openmls - 适用于 Dart 的 MLS 协议
[](https://pub.dev/packages/openmls)
[](https://github.com/djx-y-z/openmls_dart/actions/workflows/test.yml)
[](https://gist.github.com/djx-y-z/a5b2cf3b4ecf95155f76512df95d74c2)
[](LICENSE)
[](https://dart.dev)
[](https://flutter.dev)
[](https://github.com/openmls/openmls)
[OpenMLS](https://github.com/openmls/openmls) 的 Dart 绑定,提供用于安全群组消息传递的消息层安全协议 ([RFC 9420](https://www.rfc-editor.org/rfc/rfc9420.html)) 的 Rust 实现。
## 平台支持
| | Android | iOS | macOS | Linux | Windows | Web |
|-------------|---------|-------|--------|------------|---------|-----|
| **支持情况** | SDK 24+ | 13.0+ | 10.15+ | arm64, x64 | x64 | WASM |
| **架构** | arm64, armv7, x64 | arm64 | arm64, x64 | arm64, x64 | x64 | wasm32 |
## 功能特性
- **MLS 协议 (RFC 9420)**:提供前向安全和后向安全的安全群组消息传递
- **群组密钥协商**:高效的基于树的群组密钥协商 (TreeKEM)
- **后量子 (实验性)**:混合 X-Wing 密码套件 (ML-KEM-768 + X25519) — 请参阅 [后量子支持](#post-quantum-support-experimental)
- **加密存储**:所有 MLS 状态均处于静态加密 — 原生平台使用 SQLCipher,WASM 使用 Web Crypto AES-256-GCM
- **Basic 与 X.509 凭证**:支持这两种凭证类型
- **Flutter 与 CLI 支持**:适用于 Flutter 应用和独立的 Dart CLI 应用程序
- **自动构建**:通过构建钩子自动下载原生库
- **高性能**:通过 Flutter Rust Bridge 直接与 Rust 集成
## 后量子支持 (实验性)
`MlsCiphersuite.mls256XwingChacha20Poly1305Sha256Ed25519` 密码套件使用
**X-Wing** 混合 KEM ([draft-connolly-cfrg-xwing-kem](https://datatracker.ietf.org/doc/draft-connolly-cfrg-xwing-kem/)):
ML-KEM-768 与 X25519 相结合,因此只要 *任一* 组件保持未被攻破,群组密钥就是保密的。它可以防范“现在收集,以后解密” (harvest-now-decrypt-later) 的攻击。
该套件的 HPKE 操作运行在 [libcrux](https://github.com/cryspen/libcrux) 上(经过形式化验证的 ML-KEM);所有经典套件继续在 RustCrypto 上保持不变地运行。
**使用前必读 — 诚实的局限性:**
- **实验性,未标准化。** 该密码套件值 (0x004D) **未在 IANA 注册**,并且源自已过期的个人草案。IETF MLS 工作组正在标准化 *不同的* 后量子套件;当官方套件发布时,使用 X-Wing 的群组将需要进行迁移。我们将追踪官方套件并提供迁移方案。
- **互操作性有限。** 只有基于 OpenMLS 的技术栈(以及 ts-mls)支持此套件。请在所有客户端都使用此库或 OpenMLS 的封闭式部署中使用它 — 不适用于跨供应商的联合部署。
- **libcrux 版本低于 1.0 且未完全经过审计。** 它的 ML-KEM 源码已经过形式化验证(hax/F*:正确性、密钥独立性和抗 panic 特性),但编译后的二进制文件不包含任何抗侧信道攻击的验证,并且维护者自己也建议在生产环境使用前进行咨询。
- X-Wing 结构本身已经过同行评审
([如果 ML-KEM-768 或 X25519 成立,则具有 IND-CCA 安全性](https://eprint.iacr.org/2024/039))
并且其传输格式在各草案版本中一直保持稳定。
## 实现状态
| 类别 | 状态 | 描述 |
|----------|:------:|-------------|
| 群组生命周期 | 完成 | 创建、加入 (Welcome, external commit)、离开、检查 |
| 成员管理 | 完成 | 添加、移除、交换成员 |
| 消息传递 | 完成 | 使用 AAD 加密/解密应用消息 |
| 提案 | 完成 | 添加、移除、自我更新、PSK、自定义、群组上下文扩展 |
| 提交 | 完成 | 待定提案、灵活提交、合并/清除 |
| 密钥包 | 完成 | 使用选项创建 (生命周期、最后手段凭证) |
| 凭证 | 完成 | Basic 和 X.509 凭证类型 |
| 状态查询 | 完成 | 成员、epoch、扩展、ratchet tree、群组信息、PSK 导出 |
| 存储 | 完成 | 通过 `MlsEngine` 进行静态加密 (SQLCipher / Web Crypto) |
## 安装说明
将其添加到您的 `pubspec.yaml` 中:
```
dependencies:
openmls: ^x.x.x
```
在构建期间,原生库会通过 Dart 构建钩子自动下载。
最终用户**无需 Rust 环境** — 预编译的二进制文件将从 GitHub Releases 下载。
## 用法
```
import 'dart:convert';
import 'dart:typed_data';
import 'package:openmls/openmls.dart';
void main() async {
// Initialize the library
await Openmls.init();
// Create an MlsEngine with encrypted storage.
// - Native: SQLCipher database at the given file path
// - Web: IndexedDB with AES-256-GCM encryption via Web Crypto API
// Use ":memory:" for ephemeral in-memory storage (testing).
final encryptionKey = Uint8List(32); // 32-byte key — store in platform secure storage!
final engine = await MlsEngine.create(
dbPath: ':memory:',
encryptionKey: encryptionKey,
);
// Generate signing key pair
final ciphersuite = MlsCiphersuite.mls128DhkemX25519Aes128GcmSha256Ed25519;
final keyPair = MlsSignatureKeyPair.generate(ciphersuite: ciphersuite);
final signerBytes = serializeSigner(
ciphersuite: ciphersuite,
privateKey: keyPair.privateKey(),
publicKey: keyPair.publicKey(),
);
// Create a group
final config = MlsGroupConfig.defaultConfig(ciphersuite: ciphersuite);
final group = await engine.createGroup(
config: config,
signerBytes: signerBytes,
credentialIdentity: utf8.encode('alice'),
signerPublicKey: keyPair.publicKey(),
);
print('Created group: ${group.groupId}');
// Close engine (releases DB connection and encryption key resources)
await engine.close();
// Clean up FRB runtime (optional, for CLI apps exiting)
Openmls.cleanup();
}
```
## 存储
所有 MLS 状态都通过 `MlsEngine` 存储在 Rust 管理的加密数据库中:
| 平台 | 后端 | 加密方式 |
|----------|---------|------------|
| 原生 (iOS, Android, macOS, Linux, Windows) | SQLCipher | AES-256 全库加密 |
| Web (WASM) | IndexedDB | 通过 `crypto.subtle` 进行基于值的 AES-256-GCM 加密 |
```
// Create engine with a 32-byte encryption key.
// Store the key in platform secure storage (Keychain, Android Keystore, etc.)
final engine = await MlsEngine.create(
dbPath: 'mls_data.db', // file path on native, IDB name on web
encryptionKey: myKey, // 32-byte AES-256 key
);
// All operations go through the engine
final group = await engine.createGroup(...);
await engine.addMembers(...);
// Close the engine to release the DB connection and encryption key resources.
// After close, all operations fail with "MlsEngine is closed".
// Useful for screen lock / app background scenarios.
await engine.close();
// Re-create from secure storage on unlock
final engine2 = await MlsEngine.create(dbPath: 'mls_data.db', encryptionKey: myKey);
```
在 WASM 上,加密密钥通过 Web Crypto API 作为**不可提取的 `CryptoKey`** 导入。原始密钥字节在导入后会立即从 WASM 内存中清零。
## 已知局限
### Web:不支持 `flutter build web --wasm` (dart2wasm)
此包适用于标准的 `flutter build web` (dart2js) 目标。当宿主应用程序使用 `flutter build web --wasm` / `flutter run -d chrome --wasm` (dart2wasm) 编译时,它目前**无法**使用。对 Rust 端的调用会失败并提示:
```
Type 'JSValue' is not a subtype of type 'List' in type cast
```
这是 [`flutter_rust_bridge`](https://github.com/fzyzcjy/flutter_rust_bridge) 中的上游限制 — 它生成的 Dart 解码器依赖于隐式 JS 数组转换,这在 dart2js 上有效,但在 dart2wasm 下会失败。这种模式硬编码在 FRB 的代码生成模板中,因此它会影响所有基于 FRB 的 Dart 包,而不仅仅是这个包。上游追踪:[flutter_rust_bridge#2575](https://github.com/fzyzcjy/flutter_rust_bridge/issues/2575)。
| 命令 | 状态 |
|---------|--------|
| `flutter run -d chrome` | 可用 (dart2js) |
| `flutter build web` | 可用 (dart2js) |
| `flutter run -d chrome --wasm` | 不受支持 (dart2wasm) |
| `flutter build web --wasm` | 不受支持 (dart2wasm) |
openmls 的 Rust 核心在这两种模式下均以 `.wasm` 模块交付 — `--wasm` 仅更改 *Dart* 代码的编译目标。加密性能和功能是等效的。
## 从源码构建
### 面向最终用户
**无需设置!** 预编译的原生库会在 `flutter build` 期间自动从 GitHub Releases 下载。
### 面向贡献者 / 源码构建
如果您想从源码构建(或预编译的二进制文件不可用):
- [Flutter](https://flutter.dev/) 3.38+
- [FVM](https://fvm.app/) (可选,用于版本管理)
- **Rust 工具链** (1.88+):
- [rustup](https://rustup.rs/) - Rust 工具链安装程序
- `cargo` - Rust 包管理器(随 rustup 一起安装)
### 设置
```
# Clone 仓库
git clone https://github.com/djx-y-z/openmls_dart.git
cd openmls_dart
# 安装 FVM 及依赖
make setup
# 生成 Dart bindings
make codegen
# 构建 native library
make build
# 运行测试
make test
# 查看所有可用命令
make help
```
### 开发 Rust API
1. 在 `rust/src/api/` 中添加您的 Rust 函数:
```
// rust/src/api/greeting.rs
pub fn greet(name: String) -> String {
format!("Hello, {}!", name)
}
```
2. 在 `rust/src/api/mod.rs` 中注册该模块:
```
pub mod greeting;
```
3. 生成 Dart 绑定:
```
make codegen
```
4. 构建并测试:
```
make build
make test
```
### 构建原生库
原生库已预构建,并通过构建钩子自动下载。
如果您需要在本地构建它们:
```
# 为当前平台构建
make build
# 使用特定 target 构建
make build ARGS="--target aarch64-apple-darwin"
# 为 Android 构建
make build-android
# 为 Web (WASM) 构建
make build-web
```
## CI / 版本管理
```
# 检查新的 openmls 版本
make check-new-openmls-version
# 检查新的 copier template 版本
make check-template-updates
# 检查 deployment target 一致性 (iOS/macOS/Android)
make check-targets
# 更新 Cargo.lock 依赖
make rust-update
# 生成 AI 支持的 changelog 条目(需要 AI_MODELS_TOKEN)
make update-changelog ARGS="--version v1.0.0"
```
CI 每天会自动检查 openmls 的新版本,并创建包含以下内容的 PR:
- 更新后的 `pubspec.yaml` 和版本徽章
- 更新后的 `Cargo.lock` (如果成功)
- 重新生成的 FRB 绑定 (如果成功)
- AI 生成的 CHANGELOG 条目 (如果配置了 `AI_MODELS_TOKEN` 密钥)
它每天还会检查 copier 模板更新,并创建包含更新日志和说明的通知 PR。
## 架构
```
┌─────────────────────────────────────────────────┐
│ OpenMLS (Rust crate) │ Core MLS implementation
├─────────────────────────────────────────────────┤
│ MlsEngine + EncryptedDb (Rust) │ Encrypted storage layer
├─────────────────────────────────────────────────┤
│ rust/src/api/*.rs (Rust wrappers) │ FRB-annotated functions
├─────────────────────────────────────────────────┤
│ lib/src/rust/*.dart (FRB generated) │ Auto-generated Dart API
├─────────────────────────────────────────────────┤
│ Your Dart application code │ Uses MlsEngine
└─────────────────────────────────────────────────┘
```
## 安全说明
**关键属性:**
- **MLS 协议 (RFC 9420)** - 具有前向安全和后向安全特性的标准化群组密钥协商
- **Rust 实现** - 所有加密操作均在 Rust 中运行 (带有 RustCrypto 后端的 OpenMLS;实验性的 X-Wing 后量子 KEM 委派给 libcrux)
- **静态加密** - 所有 MLS 状态均通过 SQLCipher (原生) 或 Web Crypto AES-256-GCM (WASM) 进行加密
- **WASM 上的 Web Crypto** - 加密密钥通过 `crypto.subtle` 存储为不可提取的 `CryptoKey` — 原始字节永远不会保留在 WASM 内存中
- **内存安全** - Rust 的所有权模型可防止与内存相关的漏洞
- wrapper 层中**没有 `unsafe` 代码** (单线程 WASM 上的 `CryptoKey` 的 `Send + Sync` 除外)
**最佳实践:**
- 使库保持更新至最新版本
- 将 32 字节的加密密钥存储在平台安全存储中 (Keychain, Android Keystore, `flutter_secure_storage`)
- 切勿记录或暴露序列化的密钥材料 (`signer.serialize()`, 私钥)
- 对敏感数据 (序列化的密钥、共享密钥) 使用 `SecureBytes.wrap()` 或 `.zeroize()` — 参阅 [SECURITY.md](SECURITY.md)
- 按顺序处理 MLS 消息,以保持群组状态的一致性
- **Web 部署:** 启用严格的 CSP 头 (`script-src 'self'`) 并通过 HTTPS 提供服务
有关完整的安全准则,请参阅 [SECURITY.md](SECURITY.md)。
## 安全性
有关安全策略和报告漏洞,请参阅 [SECURITY.md](SECURITY.md)。
## 许可证
本项目基于 MIT 许可证授权 - 有关详细信息,请参阅LICENSE](LICENSE) 文件。
## 相关项目
- [OpenMLS](https://github.com/openmls/openmls) - 底层的 Rust MLS 库
- [RFC 9420](https://www.rfc-editor.org/rfc/rfc9420.html) - 消息层安全协议
- [Flutter Rust Bridge](https://cjycode.com/flutter_rust_bridge/) - Dart/Flutter <-> Rust 绑定生成器
完整的 API 参考
**密钥包**: `createKeyPackage`, `createKeyPackageWithOptions` **群组生命周期**: `createGroup`, `createGroupWithBuilder`, `joinGroupFromWelcome`, `joinGroupFromWelcomeWithOptions`, `inspectWelcome`, `joinGroupExternalCommit`, `joinGroupExternalCommitV2` **状态查询**: `groupId`, `groupEpoch`, `groupIsActive`, `groupMembers`, `groupCiphersuite`, `groupOwnIndex`, `groupCredential`, `groupExtensions`, `groupPendingProposals`, `groupHasPendingProposals`, `groupMemberAt`, `groupMemberLeafIndex`, `groupOwnLeafNode`, `groupConfirmationTag`, `exportRatchetTree`, `exportGroupInfo`, `exportSecret`, `exportGroupContext`, `getPastResumptionPsk` **变更操作**: `addMembers`, `addMembersWithoutUpdate`, `removeMembers`, `selfUpdate`, `selfUpdateWithNewSigner`, `swapMembers`, `leaveGroup`, `leaveGroupViaSelfRemove` **提案**: `proposeAdd`, `proposeRemove`, `proposeSelfUpdate`, `proposeExternalPsk`, `proposeGroupContextExtensions`, `proposeCustomProposal`, `proposeRemoveMemberByCredential` **提交/合并**: `commitToPendingProposals`, `mergePendingCommit`, `clearPendingCommit`, `clearPendingProposals`, `setConfiguration`, `updateGroupContextExtensions`, `flexibleCommit` **消息**: `createMessage`, `processMessage`, `processMessageWithInspect`, `mlsMessageExtractGroupId`, `mlsMessageExtractEpoch`, `mlsMessageContentType`标签:Dart, Flutter, MLS协议, 可视化界面, 安全通信, 密码学, 手动系统调用, 端到端加密