减少对服务端的信任依赖
威胁模型包含服务端失陷场景。消息正文的加解密在客户端完成;服务端处理密文以及路由、送达和安全管理所需的元数据。
Security Architecture Whitepaper
安全不是一份功能清单,而是一连串架构选择。
本文档列出幽云轩当前已实现的密码学与协议机制,以及清晰的演进路线——
为技术评估、尽职调查与合作洽谈而写。
Design Tenets
具体机制从这四条原则展开,并通过代码、协议状态和测试结果说明各自的保护范围。
威胁模型包含服务端失陷场景。消息正文的加解密在客户端完成;服务端处理密文以及路由、送达和安全管理所需的元数据。
关键公钥发生未经确认的变更时,客户端会先暂停发送并提示用户核验,避免仅显示提醒后继续传输。
身份校验锚定在用户设备,并通过本地公钥固定和面对面安全码补充验证,减少单独依赖服务端声明带来的风险。
按功能所需处理数据,能留在设备上的尽量不上传;消息密文按公开策略处理,必要运行数据和安全日志依照隐私政策及适用法律保存。
Threat Model
一个成熟的安全系统不靠「相信坏事不会发生」,而是预设它会发生,再用机制兜住。下面是我们明确防御的攻击面,以及对应的落地手段。
假设
攻击者取得数据库 → 可能接触消息密文与必要元数据;正文解密私钥不存放在服务端,正文保护仍取决于端侧密钥和协议状态安全。
假设
有人在网络中间窃听 → 全链路 TLS;WS 鉴权用一次性 ticket,会话 token 不进 URL、不落 access log。
假设
服务端下发的对方公钥发生变化 → 客户端通过 TOFU 固定公钥、变更告警与发送闸门提示用户重新核验。
假设
token 在某处泄露 → JWT 锁定签名算法 + token 版本号,注销即全部失效;同账号仅单设备在线。
假设
密码被猜中或撞库 → 新设备登录需经原设备审批;预先设置的二级恢复密码提供另一条验证路径,降低未授权登录风险。
假设
批量探测用户、刷接口、振铃骚扰 → 好友闸门 + 按 IP/账号限流退避 + 帧大小上限,把可被滥用的入口逐个收口。
假设
设备长期私钥未来被取得 → Android / Windows 的 1v1 双棘轮会逐条推进消息密钥,用于降低当前状态泄露对更早消息的影响。
假设
有人克隆整机或迁移账号文件试图冒名 → 身份密钥按账号命名空间隔离、本地库按用户分区;服务端会拒收已被其他账号占用的公钥(409 key_in_use)。
假设
通过时间、对象和频率分析通信关系 → 通信元数据不属于消息正文,也是端到端加密系统仍需治理的范围。现阶段通过数据最小化、权限控制和保留策略降低暴露,后续措施列入演进路线。
Cryptographic Primitives
原语选择和参数使用决定协议基础。下表列出当前实现采用的主要算法,并结合代码审查、单元测试和跨端向量持续复核。
| 用途 | 算法 / 参数 | 说明 |
|---|---|---|
| 消息内容加密 | AES-256-GCM | 认证加密(AEAD),每条消息独立随机密钥与 IV |
| 初始密钥协商(1v1) | X3DH · X25519 + Ed25519 | 用对方预密钥束协商共享密钥;SPK 经 Ed25519 签名验签,含一次性预密钥 |
| 前向保密棘轮(1v1) | Double Ratchet | X25519 DH 棘轮 + HKDF-SHA256 对称棘轮,逐消息派生密钥,泄露不回溯 |
| 群组前向保密 | Sender Keys | 每发送者链式棘轮,成员变动触发轮换(真机验收中) |
| 密钥派生 | HKDF-SHA256 / HMAC-SHA256 | 根密钥、链密钥、消息密钥的派生与扩展 |
| 会话密钥封装(回退 / 鸿蒙) | RSA-OAEP-SHA256 | 用接收方公钥封装消息 AES 密钥;作为棘轮的兼容回退路径 |
| 随机数生成 | CSPRNG | 密钥、IV、ticket 均来自密码学安全随机源 |
| 备份密钥派生 | PBKDF2 · 600,000 次 | 口令派生主密钥,再以信封加密保护数据密钥 |
| 备份数据加密 | AES-GCM | 信封加密:数据密钥保护内容,主密钥保护数据密钥 |
| 公钥指纹 / 安全码 | SHA-512 / SHA-256 | 面对面比对的安全码与二维码指纹 |
End-to-End Encryption
消息正文在发送方设备上加密,到接收方设备上解密。服务端负责鉴权、路由和密文转发,不持有正文解密私钥。
每条消息使用独立的 AES-256 密钥。Android / Windows 的 1v1 会话由双棘轮逐消息派生该密钥(详见下节「前向保密」),其余路径以接收方 RSA 公钥封装作为兼容回退,以缩小单条密钥泄露的影响范围。
文字、图片、语音、文件、引用回复和群聊消息使用客户端加密;语音 / 视频通话媒体流使用 WebRTC DTLS-SRTP,每次通话独立协商临时密钥。
sender_id 由服务端从鉴权 token 中取出,而非直接采用客户端自报值,用于防止客户端伪造发件人编号。
单聊密文送达后通常在约 10 分钟内由清理任务处理,群消息按各群设置的保留时长处理;必要运行数据和安全日志依照隐私政策及适用法律保存。
Forward Secrecy · Double Ratchet
仅用长期密钥封装时,长期私钥泄露可能扩大历史密文的风险。Android / Windows 的 1v1 会话采用公开的 X3DH + 双棘轮(Double Ratchet)设计,逐消息推进密钥,用于提供前向保密并在后续 DH 棘轮更新后恢复会话保密性。
首次会话用对方预密钥束(已签名预密钥 SPK + 一次性预密钥 OPK)做 X25519 三 / 四重 DH,协商出独立共享密钥;SPK 由 Ed25519 身份密钥签名,客户端先验签再建会话。服务端仅充当预密钥目录与不透明信封,1v1 消息表零改造。
X25519 DH 棘轮与 HKDF-SHA256 对称棘轮联动:每条消息使用独立派生密钥并推进链状态,用于降低当前会话状态泄露对更早消息的影响;后续 DH 棘轮更新可重新建立新的会话密钥材料。
1v1 的文字、图片、语音、视频、文件与引用回复均已纳入棘轮:媒体内容仍以随机 per-file 密钥自加密,而「封装这把密钥」改由棘轮承担(前缀 r1: 双轨判别)。
群聊采用 Sender Keys 链式棘轮:每位发送者维护独立发送链,成员变动触发密钥轮换(PCS),把前向保密延伸到群聊文本、媒体与引用,同时兼顾大群转发效率。
棘轮与旧 RSA 封装双轨并存:对端尚未升级或暂不支持棘轮时回退 RSA-OAEP;客户端根据对端能力选择兼容路径。
安全码 / 指纹以 Ed25519 身份密钥(IK)为锚;对端身份密钥变化时显示待核验提示,RSA 公钥发生未经确认的变化时继续由发送闸门拦截。
Identity & Key Pinning
端到端加密还需要确认公钥归属。我们结合「首次信任 + 公钥固定 + 变更告警 + 面对面验证」降低密钥被替换的风险,相关指纹算法在四端逐字节对齐。
首次见到对方公钥即固定到本地加密存储(KeyPinStore)。此后服务端再下发的公钥只作比对,不会被静默覆盖。
每次发送前与服务端最新公钥比对(reconcile);一旦公钥变化,会话页弹出红色告警横幅,提示可能存在中间人或对方换机。
公钥处于「已变更」状态时,发送被直接拦截而非仅提示,直到用户确认。所有 1v1 发送点统一走 requirePinnedKey 闸门。
提供可当面逐字比对的安全码(基于 SHA-512 取 60 字节分组),用于线下确认双方看到的是同一把公钥。
面对面加好友的二维码载荷为 邀请码#公钥指纹;兑换时自动比对指纹,一致即标记为「已当面验证」,不符则自动撤销添加并告警。
公钥更新接口非任意可改:同钥幂等、首次放行,再次变更需密码或「新鲜 token 窗口(5 分钟)」,并记录 KeyVersion 随资料下发。被盗的存量 token 改不动公钥。
每个账号的棘轮身份密钥按 userId 命名空间隔离、本地数据库按用户分区;服务端检测到公钥或身份签名已被其他账号占用时会拒收(409 key_in_use),客户端随后为当前账号生成新的身份材料。
Protocol Hardening
原语正确不等于协议安全。我们结合专项代码审查和回归测试,对实时信令与接口逐项加固;下列条目说明已实施的控制措施。
WebSocket 入站帧限定为客户端可发起的类型;message / recall 等操作通过 HTTP 鉴权路径处理,用于阻止伪造登出、伪造撤回或跳过好友校验直接投递。
聊天室历史拉取会校验调用者成员身份,非成员返回 404,用于防止通过房间码枚举越权读取密文与元数据(IDOR)。
呼叫信令投递前校验好友关系,非好友的应答与「离线」表现一致,用于降低按 userID 枚举、振铃骚扰和在线状态探测风险。
群消息在写入前校验成员身份,非成员请求不会进入群消息表。
校验时锁定签名算法(WithValidMethods HS256),引入用户级 token 版本号,注销即令旧 token 失效。
移除二级密码的弱兜底逻辑(未设置即禁用恢复),恢复失败纳入账号级指数退避,降低恢复路径被用于账号接管的风险。
WS 帧 SetReadLimit 1MiB + HTTP body 大小上限中间件,防巨帧 / 巨包内存耗尽型 DoS。
客户端会话 token 使用平台可用的受保护存储(EncryptedSharedPreferences / 加密本地库);具体保护强度取决于平台和设备安全能力。
Transport & Network
内容已端到端加密,传输与凭据管理也不能松。这一层管的是 token、密钥、连接与滥用防护。
HTTP 与 WebSocket 经 TLS / WSS 传输,会话 token、登录密码与元数据在网络链路上受到传输加密保护,用于降低窃听和会话劫持风险。
通话中继不再用静态长期口令,改为 coturn REST 临时凭据:username = 过期unix:userID,credential 为 HMAC-SHA1,到期自动失效。已部署并实测中继收发。
建立 WebSocket 前先换取一次性 ticket(24 字节 CSPRNG、30 秒有效、不可重放),避免长效 JWT 进入 URL 与访问日志。
JWT 密钥、厂商推送 secret 等移出代码库(config → secrets → env 三层加载);启动时拒绝空或默认 JWT 密钥。
登录 / 注册按 IP 固定窗口限流,账号维度采用指数退避;Gin 仅信任回环地址上的 Nginx 代理(127.0.0.1 / ::1),外部请求中的 X-Forwarded-For 不会被直接采信。
媒体 blob 绑定收发双方或群成员,下载前校验归属,未授权请求返回 404,用于防止直链遍历造成越权下载(IDOR)。
Account & Privacy by Architecture
很多隐私风险来自产品默认形态,而非加密强度。我们把这些默认值逐条翻了过来。
同账号仅单设备在线,新设备须经原设备批准;预先设置的二级恢复密码提供另一条验证路径,用于降低未授权登录风险。
不提供手机号搜索、附近的人或陌生推荐;用户通过邀请码或当面二维码发起好友联系。
Android 端提供本地会话空间,内容保存在当前设备并且不经服务器转发;入口可在设置中显示或收起。
聊天记录备份采用信封加密(口令 PBKDF2 派生 + AES-GCM);备份文件和口令由用户保管,恢复过程依赖正确口令。
单聊密文送达后通常在约 10 分钟内由清理任务处理,群消息按群组设置的保留时长处理;必要安全日志另按隐私政策保存。
服务端不持有解密消息正文所需的私钥;账号信息、通信元数据和安全日志不属于消息正文,依照隐私政策处理。
Endpoint Protection
端到端加密保护传输中的消息正文,但内容最终仍会在设备上显示。截屏、锁屏通知、剪贴板和日志属于端侧风险面,需要额外控制。
Android 聊天与文档界面使用 FLAG_SECURE,限制系统截图、录屏、投屏和「最近任务」快照;Windows 端敏感窗口使用 WDA_EXCLUDEFROMCAPTURE 请求系统从受支持的屏幕捕获路径中排除窗口。具体效果仍受操作系统、设备和捕获方式影响。
锁屏是一块「零认证」的显示面。通知采用双版本机制:安全锁屏上仅显示「收到新消息」,发件人与内容要解锁后才可见;离线推送仅携带极简提醒,消息正文不经厂商推送通道。
复制的消息与邀请码由系统级排除标记保护:不进剪贴板历史(Win+V)、不上云剪贴板跨设备漫游,并请求剪贴板监视类工具跳过;30 秒后自动清空,清空前校验剪贴板未被覆盖,不误伤用户随后复制的其它内容。
密钥与棘轮会话状态加密落盘:Android 使用系统密钥库保护;Windows 主密钥经 DPAPI(绑定当前登录用户)叠加应用专属熵封装,用于提高批量凭据窃取的成本;棘轮会话状态不纳入应用备份。
正式版减少网络报文调试输出并对鉴权凭据脱敏;WS 鉴权使用一次性 ticket,长效凭据不进入 URL。提交系统日志或故障报告前仍应检查其中是否含有账号、设备或运行环境信息。
Cross-Platform Parity
安全能力最怕「这个平台有、那个平台漏」。我们的客户端各自原生开发,但密码学与校验逻辑严格对齐——尤其是公钥指纹 / 安全码的算法,跨端逐字节一致,才能面对面互验。同时我们如实区分「算法一致」与「保障等级一致」:密钥的本地保护强度随各平台安全能力(硬件密钥库 / 系统级封装)分级,威胁模型按最弱参与端计算——这也是我们持续加固桌面端本地防护的原因。
Kotlin + Compose
公钥固定 + 双棘轮前向保密
Compose Desktop
加密本地存储 + 双棘轮前向保密
ArkTS 原生
公钥固定 / 安全码对齐;双棘轮与群 Sender Keys 已实现(真机联调中)
Roadmap
我们参考公开、成熟的现代端到端加密协议设计。Android / Windows 的 1v1 前向保密已落地;下列项目仍处于真机验收、跨端对齐或方案评估阶段。
群聊 Sender Keys(文本 / 媒体 / 引用)已在 Android 与 Windows 实现并通过单元测试,正进行多端真机验收:首发分发、成员变动轮换(PCS)、离线补发、跨端互通,以及「收到即消费」的健壮性加固。
鸿蒙端的双棘轮(1v1)与群 Sender Keys 已完成与 Android / Windows 对齐的实现,正进行真机联调验收;与四端一致的公钥固定 / 安全码已就位。验收通过后即与其余两端享有同等的前向保密。
通话媒体的前向保密由 DTLS-SRTP 临时密钥天然提供;真正的加固点在抗信令中间人:呼叫双方现将各自的 DTLS 证书指纹经双棘轮加密信道(与消息同一已验证身份)互相送达并比对——指纹被调包即自动终止通话,验证通过则在通话界面亮出「身份已验证」。Android / Windows 双端就位。
好友列表与会话页现已常驻显示验证状态盾标:「已当面验证」的可信关系一眼可辨;身份密钥变更待核实时切换为警示盾,处置完成后自动恢复。Android / Windows / HarmonyOS 三端一致。
端到端加密不覆盖全部通信元数据。后续工作聚焦于减少推送载荷中的身份信息、持续脱敏运行日志、明确各类元数据保留期限,并评估长度分桶等降低流量特征暴露的措施。