open-e2ee/signal-protocol-js

GitHub: open-e2ee/signal-protocol-js

一个纯 TypeScript 的 Signal Protocol 端到端加密 SDK,为跨平台应用提供后量子安全的消息通信能力。

Stars: 0 | Forks: 0

OpenE2EE # OpenE2EE Signal Protocol SDK **为 TypeScript 应用提供端到端加密消息传递。支持 Signal Protocol,默认具备后量子安全性,可在 Expo 中运行。** [![License: AGPL-3.0-or-later](https://img.shields.io/badge/license-AGPL--3.0--or--later-2f6f5e)](https://github.com/open-e2ee/signal-protocol-js/blob/main/LICENSE) [![Types: TypeScript](https://img.shields.io/badge/types-TypeScript-3178c6)](https://www.typescriptlang.org/) [![npm version](https://img.shields.io/npm/v/@open-e2ee/signal-protocol-sdk)](https://www.npmjs.com/package/@open-e2ee/signal-protocol-sdk) [![npm downloads](https://img.shields.io/npm/dw/@open-e2ee/signal-protocol-sdk)](https://www.npmjs.com/package/@open-e2ee/signal-protocol-sdk) [![Checks](https://static.pigsec.cn/wp-content/uploads/repos/cas/10/10c1084818f2e50307f497f810114bfeaa2ea3b134f514f045d90e315258b63f.svg)](https://github.com/open-e2ee/signal-protocol-js/actions/workflows/ci.yml) *与 Signal Messenger 无关。* 这是一个对公开 Signal Protocol 规范的独立实现 —— 完整声明见 [NOTICE](https://github.com/open-e2ee/signal-protocol-js/blob/main/NOTICE)。 [文档](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/GETTING_STARTED.md) · [快速开始](#quick-start) · [架构](https://github.com/open-e2ee/signal-protocol-js/blob/main/ARCHITECTURE.md) · [安全模型](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/SECURITY.md) · [协议策略](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/PROTOCOL_POLICY.md) - **纯 TypeScript。** 无原生模块,无预构建步骤,无需发布平台二进制文件。 - **你的应用在哪运行,它就在哪运行。** Expo、React Native、现代浏览器和 Node 均可通过同一个包支持。 - **默认具备后量子安全性。** PQXDH 和 ML-KEM 会话建立无需配置即可开启,并在失败时拒绝连接。 - **真正的消息传递功能。** 支持多设备、群组、密封发送者 (Sealed Sender)、加密附件和安全码。 - **可插拔的存储与中继。** 设备本地存储是必须的且完全由你掌控;中继仅是一个接口,而非托管服务。 - **AGPL-3.0-or-later 或商业许可。** 想要构建闭源产品?请发送邮件至 licensing@open-e2ee.dev。 `0.1.0-alpha.1` — 在 `1.0` 版本之前,公开 API 和持久化格式可能会发生更改。 ## 安装 ``` npm install @open-e2ee/signal-protocol-sdk ``` 直接从仓库安装也是可行的 —— 该包会在安装期间自行编译,因此 TypeScript 是唯一的构建要求: ``` npm install github:open-e2ee/signal-protocol-js ``` 适配器将它们的运行时依赖声明为可选的 peer dependencies,因此请安装你所选适配器需要的依赖(例如 `expo-sqlite` 和 `expo-secure-store`,或者 `convex`)。 ## 快速开始 两个客户端,一个进程,无需账户和服务器。中继负责保管信封;只有 Bob 的设备能将其还原为文本。 ``` import { createSignalProtocolClient } from "@open-e2ee/signal-protocol-sdk"; import { mockStore } from "@open-e2ee/signal-protocol-sdk/local/store/mock"; import { mockRelay } from "@open-e2ee/signal-protocol-sdk/remote/relay/mock"; const relay = mockRelay(); await relay.registerDevice("alice", { encryptedDeviceName: new ArrayBuffer(0) }); await relay.registerDevice("bob", { encryptedDeviceName: new ArrayBuffer(0) }); const alice = await createSignalProtocolClient({ identity: { userId: "alice" }, adapters: { storage: mockStore(), relay }, }); const bob = await createSignalProtocolClient({ identity: { userId: "bob" }, adapters: { storage: mockStore(), relay }, }); await alice.syncToServer(); await bob.syncToServer(); // Decrypted content reaches your app here, and nowhere else. bob.registerHook("onMessageDecrypted", async (message) => { console.log(`${message.senderId}: ${message.content}`); // alice: hello }); await alice.send("bob", "hello"); // the relay now holds ciphertext and metadata bob.startRelaySubscription(); // delivery and local decryption start here ``` 上面的每一个标识符都是真实的导出。这段代码块正是从本 README 中提取的,并且每次改动时都会由[本仓库的 CI](https://github.com/open-e2ee/signal-protocol-js/actions/workflows/ci.yml) 针对打包好的 package 执行测试;同样的执行流程也会在工程仓库的测试套件中运行。 下一步:[查看中继实际存储的内容](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/GETTING_STARTED.md),然后构建 [Expo + Convex 生产级客户端](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/CLIENT_COMPOSITION.md)。 ## 横向对比 数据于 2026-07-24 通过 GitHub 和 npm registry API 测得。列出的每个替代方案都是真正在解决实际问题的项目;下表列出的维度正是本 SDK 致力于改变的方面,而非通用的质量排名。 | | Expo / React Native | 浏览器 | 持续维护 | 后量子安全 | TypeScript 原生 | 商业许可 | |---|---|---|---|---|---|---| | **`@open-e2ee/signal-protocol-sdk`** | 是 | 是(浏览器存储为实验性功能) | 是 — `0.1.0-alpha`,活跃开发中 | 是 — 支持 PQXDH + ML-KEM,默认开启且失败即拒绝连接 | 是 | 是 | | [`@signalapp/libsignal-client`](https://github.com/signalapp/libsignal) | 否 — 仅限 Windows、macOS 和 Linux 的预构建原生二进制文件 | 否 | 是 — 非常活跃 | 是 | 否 — Rust 核心配合 TypeScript 绑定 | 否(仅限 AGPL-3.0) | | [`libsignal-protocol-javascript`](https://github.com/signalapp/libsignal-protocol-javascript) | 否 | 是 | 否 — 已归档,最后更新于 2021-08-04 | 否 | 否 — JavaScript | 否(GPL-3.0) | | [`@privacyresearch/libsignal-protocol-typescript`](https://github.com/privacyresearchgroup/libsignal-protocol-typescript) | 无 React Native 使用文档 | 是 | 否 — 最后一次 npm 发布于 2023-05-06,最后一次仓库更新于 2023-07-18 | 否 | 是 | 否(GPL-3.0) | | [`ts-mls`](https://github.com/LukaJCB/ts-mls) | 是 | 是 | 是 — 非常活跃 | 是 | 是 | 否(MIT) | `ts-mls` 实现了 [MLS (RFC 9420)](https://www.rfc-editor.org/rfc/rfc9420.html),这是一种具有不同属性的不同协议 —— 如果 MLS 适合你的产品,它是一个很好的库,此表格无意贬低它。`@signalapp/libsignal-client` 是 Signal Messenger 自身使用的实现;其 README 声明不支持在 Signal 之外使用。 ## 信任与验证 密码学需要的是证据而非溢美之词,因此这里列出了我们具备什么以及不具备什么。 **审计状态。** 尚未经过审计。目前已计划进行独立审查;但尚未确定审计机构及日期。此处任何内容均不应被视为第三方的保证声明。 **安全模型与协议策略。** [安全模型](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/SECURITY.md)说明了威胁模型、支持与不支持的范围、存储边界以及资源限制。[协议策略](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/PROTOCOL_POLICY.md)说明了支持哪些协议模式以及哪些在失败时会拒绝连接。 **规范,按版本固定。** 本实现遵循基于以下发布规范的自有版本化配置: | 规范 | 版本 | |---|---| | [X3DH](https://signal.org/docs/specifications/x3dh/) | Revision 1, 2016-11-04 | | [PQXDH](https://signal.org/docs/specifications/pqxdh/) | Revision 3, 2023-05-24 (最后更新于 2024-01-23) | | [Double Ratchet](https://signal.org/docs/specifications/doubleratchet/) | Revision 4, 2025-11-04 | | [Sesame](https://signal.org/docs/specifications/sesame/) | Revision 2, 2017-04-14 | | [ML-KEM Braid](https://signal.org/docs/specifications/mlkembraid/) | Revision 1, 2025-02-21 (最后更新于 2025-09-26) | | [FIPS 203 (ML-KEM)](https://csrc.nist.gov/pubs/fips/203/final) | Final, 2024-08-13 | | [RFC 8032 (Ed25519)](https://www.rfc-editor.org/rfc/rfc8032.html) | — | 该配置是刻意与 Signal Messenger 的部署有所区别的,并在此声明:ML-KEM-1024 密钥和密文标记为 `0x0A`,不同于第 3 轮 Kyber1024 的 `0x08` 标记,并且 Ed25519 身份组件执行的是普通的 RFC 8032 签名,而非 XEdDSA。我们不声称与 Signal Messenger 具有通用的网络协议兼容性。确切的边界在[安全模型](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/SECURITY.md)中进行了说明。 **依赖项:7 个。** 七个直接的生产环境依赖项 —— `@noble/ciphers`、`@noble/curves`、`@noble/hashes`、`@noble/post-quantum`、`async-lock`、`protobufjs`、`unique-names-generator` —— 总共解析为 8 个包,第 8 个是通过 `protobufjs` 引入的 `long`。依赖树中的其他所有内容均为开发依赖或可选的 peer dependency。 **自动化检查。** 已发布的仓库是私有工程仓库通过白名单过滤后的机械化导出;自动化检查在私有仓库中进行,且必须通过后才能进行导出。最近一次于 2026-07-24 的完整运行涵盖了 351 个模块和 5,875 个断言,全部通过(跳过 1 个)。[保证摘要](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/ASSURANCE.md)说明了这些检查涵盖的内容、未发布的内容以及原因。发布的公开仓库在每次更改时都会在其 [CI](https://github.com/open-e2ee/signal-protocol-js/actions/workflows/ci.yml) 中运行其自身的构建、类型检查和生产环境依赖审计。 **关于常数时间姿态的坦诚。** JavaScript 引擎不提供机器级别的常数时间保证,本 SDK 也无法凭空发明一种。现有的只是针对特定路径的尽力而为的源码级处理:对等长的 MAC 和身份字节进行全量扫描比较,在掩码选择之前对两个解封装候选项进行固定工作量的派生,以及针对特定重放和身份验证路径的等量工作量拒绝填充。这些并不是时间等价性证明。受秘密影响的余数和压缩算术依然存在,并且 JIT 编译、内存分配、垃圾回收和缓存效应仍然可以被观测到。`secureZeroBytes()` 仅会覆盖传入给它的那个特定 typed array,不会覆盖更多 —— 既不包括副本,也不包括字符串,更不包括引擎临时数据。威胁模型不涵盖同进程内的恶意代码或高安全要求的同驻时序攻击者,并且文档中已明确声明了这一点。 **报告漏洞。** 请发送邮件至 security@open-e2ee.dev,而不是开启一个 issue。我们将在 48 小时内确认收到,并在 7 天内进行初步评估;完整策略详见 [SECURITY.md](https://github.com/open-e2ee/signal-protocol-js/blob/main/SECURITY.md)。 ## 文档 - [入门指南](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/GETTING_STARTED.md) — 安装说明、心智模型以及第一个可运行的客户端。 - [包概览](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/PACKAGE_SURFACE.md) — 根导出、所有子路径、适配器实现及核心概念。 - [实战指南](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/RECIPES.md) — 消息流、协议策略、多设备、附件和用户名。 - [客户端组合](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/CLIENT_COMPOSITION.md) — 结合 Expo 和 Convex 的生产级组合。 - [架构](https://github.com/open-e2ee/signal-protocol-js/blob/main/ARCHITECTURE.md)与[适配器](https://github.com/open-e2ee/signal-protocol-js/blob/main/ADAPTERS.md) — 层次模型与组合边界。 - [集成接口](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/INTERFACES.md) — 为自定义存储、保险库、中继和对象存储需实现的接口。 - [错误处理](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/ERROR_HANDLING.md)和[故障排除](https://github.com/open-e2ee/signal-protocol-js/blob/main/TROUBLESHOOTING.md)。 - [E2EE 概念](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/E2EE.md) — 当中继无法读取数据时,你的架构会发生哪些变化。 - [API 参考](https://github.com/open-e2ee/signal-protocol-js/blob/main/docs/api/README.md) — 根据导出的声明生成。 ## 许可证与免责声明 采用 `AGPL-3.0-or-later` 许可;详情见 [LICENSE](https://github.com/open-e2ee/signal-protocol-js/blob/main/LICENSE)。对于无法履行 AGPL 义务的专有产品,可通过 licensing@open-e2ee.dev 获取商业授权。 本软件按“原样”提供,不附带任何类型的明示或暗示的保证或条件。在适用法律允许的最大范围内,版权所有者和贡献者对因使用本软件而产生的任何损害概不负责。应用程序仍需负责根据自身需求评估此 SDK,并确保其部署、存储、身份验证、授权和运行的安全。本摘要不修改许可证内容;完整的免责声明和责任限制请参见 GNU Affero General Public License 的第 15 和第 16 条。
标签:React Native, Signal协议, TypeScript, 后量子密码学, 安全插件, 端到端加密, 自动化攻击, 跨平台开发