vaazhen/chaos-e2ee-messenger

GitHub: vaazhen/chaos-e2ee-messenger

一个基于 Spring Boot、React 与 Electron 构建的全栈实时端到端加密通讯应用,支持多设备加密消息收发、音视频通话信令与自托管部署。

Stars: 18 | Forks: 1

# Chaos Messenger 支持 Web 和桌面端的多设备端到端加密通讯应用。 React · Electron · Spring Boot · PostgreSQL · Redis · Kafka/Redpanda · Docker · Kubernetes [俄语版本](README.ru.md) · [验证报告](VALIDATION_REPORT.md) · [安全审计](SECURITY_AUDIT_EN.md)
## 功能 - 单聊、群聊和保存的消息; - 回复、编辑、删除、表态以及已读/已送达状态; - 加密附件和阅后即焚消息; - 输入状态、在线状态和 WebSocket 更新; - 通过 WebRTC 进行音视频通话信令传输; - 邮箱/密码和手机号认证; - 活跃设备管理和基于设备的端到端加密 (E2EE) 投递; - 支持加密备份; - Web 客户端和 Electron 桌面客户端; - Docker Compose、Kubernetes 清单和可观测性配置。 ## 端到端加密 每个客户端设备都拥有独立的加密身份。客户端使用类似 X3DH 的预共享密钥交换机制建立会话,并使用基于 WebCrypto 的 Double Ratchet 实现来加密消息。 后端会接收并存储: - 设备公钥和预共享密钥; - 加密的消息信封; - 加密的附件负载; - 账户、设备、聊天和投递元数据。 后端不会接收消息明文或客户端私钥。 ### 设备验证 对于每个远程设备,可以通过带外方式比对安全码。已验证的设备具有以下信任状态之一: ``` UNVERIFIED -> VERIFIED -> KEY_CHANGED ``` 当先前已验证设备的身份密钥发生更改时,加密操作将被阻止,直到再次对该设备进行显式验证。 ### 客户端密钥存储 私钥身份密钥、预共享密钥和棘轮会话作为加密的 IndexedDB 记录进行存储。包装密钥是不可提取的 WebCrypto 密钥。棘轮状态变更会在并发操作间进行串行化处理,以防止消息索引重用。 访问令牌保存在进程内存中。刷新令牌通过 `Secure`、`HttpOnly`、`SameSite=Strict` cookie 传递,并由后端进行轮换。 端到端加密无法保护已经被入侵的终端。在受信任域中运行的 JavaScript、恶意构建的应用程序、浏览器扩展或操作系统恶意软件,都可以在客户端运行时访问明文。 ## 实时投递 当启用 Kafka 时,后端会使用事务性发件箱。设备事件会持久化保存,并附带一个单调递增的序列号。 重新连接后,客户端将: 1. 读取上次存储的游标; 2. 从 `/api/realtime/sync` 请求遗漏的事件; 3. 按顺序应用持久化事件; 4. 处理在恢复期间缓存的 WebSocket 事件; 5. 存储新的游标。 实时投递保证至少一次。事件包含一个 `eventId`,客户端会对重复投递进行去重。 ## 架构 ``` flowchart LR WEB[React web client] --> EDGE[Caddy / Nginx / Ingress] DESKTOP[Electron client] --> EDGE EDGE --> API[Spring Boot backend] API --> PG[(PostgreSQL)] API --> REDIS[(Redis)] API --> OUTBOX[Transactional outbox] OUTBOX --> KAFKA[Kafka / Redpanda] KAFKA --> REALTIME[Realtime consumer] REALTIME --> EDGE API --> ATTACHMENTS[(Encrypted attachment storage)] API --> OBS[Actuator / Prometheus / Loki] OBS --> GRAFANA[Grafana] ``` ## 技术栈 | 层级 | 技术 | |---|---| | Web | React 18, Vite 5, WebCrypto, IndexedDB, STOMP/SockJS | | 桌面端 | Electron 33, electron-builder | | 后端 | Java 17, Spring Boot 3.5, Spring Security, JPA/Hibernate | | 数据 | PostgreSQL 16, Redis 7, Flyway | | 事件 | 兼容 Kafka 的代理 / Redpanda, 事务性发件箱 | | 可观测性 | Actuator, Prometheus, Grafana, Loki, Promtail | | 部署 | Docker Compose, Kubernetes/Kustomize, GitHub Actions | ## 快速开始 ### 环境要求 - Docker Engine; - Docker Compose v2; - 至少 4 GB 的可用内存以运行完整的本地技术栈。 ### 配置 ``` cp .env.example .env ``` 生成强密钥并替换所有 `CHANGE_ME` 的值: ``` openssl rand -base64 32 # POSTGRES_PASSWORD openssl rand -base64 32 # REDIS_PASSWORD openssl rand -base64 48 # JWT_SECRET openssl rand -base64 32 # GRAFANA_ADMIN_PASSWORD ``` 设置: ``` DOMAIN=localhost CORS_ORIGINS=https://localhost ``` 对于公共部署,请使用真实的 DNS 名称和匹配的 HTTPS 源。 ### 运行 ``` docker compose up --build -d docker compose ps docker compose logs -f backend frontend caddy ``` 打开: ``` https://localhost ``` Caddy 会对本地名称使用其本地 CA,并为有效的公共域名获取公共 TLS 证书。 停止技术栈: ``` docker compose down ``` 同时删除本地数据: ``` docker compose down -v ``` ## 本地开发 ### 后端 ``` cd backend ./mvnw spring-boot:run ``` 可以通过以下命令启动开发依赖项: ``` cd backend docker compose -f docker-compose.dev.yml up -d ``` ### 前端 ``` cd frontend npm ci npm run dev ``` Vite 开发服务器会将 `/api` 和 `/ws` 代理到 `http://localhost:8080`。 ## Electron 创建桌面端环境文件: ``` cd frontend cp .env.electron.example .env.electron ``` 设置绝对安全的 endpoint: ``` VITE_BACKEND_URL=https://messenger.example.com VITE_API_BASE=https://messenger.example.com/api VITE_WS_URL=wss://messenger.example.com/ws ``` 构建: ``` npm run electron:build ``` 当缺少必需的 endpoint 或使用不安全的协议时,构建将会失败。公共安装程序应进行代码签名;macOS 构建还应进行公证。 ## 配置 主要环境变量: | 变量 | 用途 | |---|---| | `POSTGRES_PASSWORD` | PostgreSQL 密码 | | `REDIS_PASSWORD` | Redis 密码 | | `JWT_SECRET` | JWT 签名密钥,至少 32 个字符 | | `DOMAIN` | Caddy 使用的公共主机名 | | `CORS_ORIGINS` | 精确受信任的前端源 | | `CHAOS_DEMO_ENABLED` | 启用可选的演示 endpoint | | `VAPID_PUBLIC_KEY` / `VAPID_PRIVATE_KEY` | Web Push 凭证 | | `CHAOS_KAFKA_ENABLED` | 启用 Kafka/发件箱投递 | | `KAFKA_BOOTSTRAP_SERVERS` | 兼容 Kafka 的代理地址 | | `CHAOS_ATTACHMENTS_STORAGE_PATH` | 加密附件的存储路径 | | `CHAOS_ATTACHMENTS_MAX_BYTES` | 加密附件的最大大小 | 有关完整的本地配置,请参见 `.env.example`、`backend/.env.example` 和 `frontend/.env.example`。 ## 测试 ### 后端 ``` cd backend ./mvnw verify ``` ### 前端 ``` cd frontend npm ci npm run lint npm test npm run test:coverage npm run build ``` 打包的源代码已通过 **154 个通过的前端测试和 3 个特意跳过的测试**的检查。确切结果和环境限制记录在 [VALIDATION_REPORT.md](VALIDATION_REPORT.md) 中。 ## Kubernetes `k8s/` 目录包含: - 命名空间和配置; - 后端和前端的 Deployment/Service; - Ingress; - 资源请求和限制; - 存活/就绪探针; - 水平 Pod 自动扩缩容; - PodDisruptionBudgets; - 密钥模板。 在替换镜像名称、主机名和密钥值后执行应用: ``` kubectl apply -k k8s/ ``` 对于公共生产环境部署,请使用托管型或基于 Operator 的 PostgreSQL、Redis 和 Kafka,经过测试的备份/PITR、外部密钥管理以及独立的安全测试。 ## 安全说明 - 不要提交 `.env` 文件或真实的凭证。 - 将 `/actuator` 和 Prometheus endpoint 保留在内部网络中。 - 仅通过 HTTPS 提供 Web 应用程序服务。 - 使用精确的 CORS 源;不要使用全局通配符。 - 通过密钥管理器轮换 JWT、数据库、Redis 和 VAPID 密钥。 - 在每次发布前运行后端测试套件、集成测试和数据库迁移。 - 在将该系统用于高风险通信之前,请获取独立的加密审查和渗透测试。 有关详细的安全和发布检查清单,请参见 [SECURITY_AUDIT_EN.md](SECURITY_AUDIT_EN.md) 和 [PRODUCTION_READINESS.md](PRODUCTION_READINESS.md)。 ## 许可证 基于 [Apache License 2.0](LICENSE) 授权。
标签:Electron, JS文件枚举, React, Spring Boot, Syscalls, WebRTC, 即时通讯, 子域名突变, 搜索引擎查询, 测试用例, 端到端加密, 自定义脚本, 自定义请求头, 请求拦截