端到端加密云同步
端到端加密云同步是桌面端的 Pro 功能,由三块组成:多端增量同步(多台桌面设备间自动保持一致)、快照保险箱(完整数据的加密快照,用于换机与重要节点备份)、云端→桌面明文下行通道(把云端账号下的个人内容拉回本地)。所有上行数据在本机加密后才离开设备,服务端只存密文、salt 和 iv,无法获知同步口令或明文内容。本页说明加密口径、同步序列化规则、恢复语义,以及与之配套的本机静态加密(保险柜)和数据目录布局。
核心概念
| 概念 | 说明 |
|---|---|
| 同步口令 | 派生加密密钥的唯一输入,只存本机内存,不落盘、不上传;忘记即无法解密云端数据 |
| 增量 op | 本机新增/修改/删除被捕获为一条操作记录,加密后进 outbox 等待推送 |
| 快照 | 全量数据的加密包,云端按账号轮转保留,用于新设备引导与手动备份 |
| AAD | AES-GCM 的附加认证数据,绑定密文用途:增量 op 用 psb-sync:v1,快照用 psb-backup:v1 |
| 明文下行通道 | 云端账号下的个人内容(网页端写入的)可拉回桌面端本地库的通道 |
| 保险柜(vault) | 本机磁盘的整库加密,锁定后磁盘不留明文数据库;与云同步相互独立、可叠加 |
加密口径
密钥与加解密实现于 app/services/sync_crypto.py:
- 密钥派生:PBKDF2-HMAC-SHA256,600,000 次迭代(
PBKDF2_ITERATIONS),从同步口令派生 32 字节 AES-256 密钥;参数与前端一致; - 加密算法:AES-256-GCM,密文被篡改会直接解密失败;
- AAD 分用途绑定:增量 op 用
SYNC_AAD = "psb-sync:v1",快照/备份用BACKUP_AAD = "psb-backup:v1"——防止把一种用途的密文挪到另一种用途重放。快照恢复必须显式传expectedAad='psb-backup:v1'(sync_agent.restore_from_snapshot中decrypt_op(..., BACKUP_AAD)),AAD 不匹配即解密失败; - salt:公开随机数,绑定云端账号持久保存,换新设备用同一口令即可重新派生同一密钥。
同步序列化:捕获侧与应用侧
同步能覆盖哪些列,由两侧各自决定(app/services/sync_capture.py / app/services/sync_agent.py):
| 侧 | 机制 | 口径 |
|---|---|---|
| 捕获侧 | _row_to_payload 整行通用序列化 | 模型行有什么列就打包什么列,新增内容列自动随同步走,无需改同步代码 |
| 应用侧 | _coerce_columns 列白名单 | 下行应用时只写目标库模型真实存在的列,payload 里多出来的列静默丢弃 |
推论:版本错位窗口内,老版本桌面端收到含新列的 op 会静默丢列,且 LWW(最新修改优先)不会事后补回——多端使用时保持各端版本一致可避免此类丢失。
其余同步语义:
- 节拍:调度器 60 秒一拍(
_sync_tick),遍历已解锁用户做推送/拉取;约一分钟级收敛,不是毫秒级实时; - 冲突:按记录修改时间最新者胜(LWW);删除以墓碑机制同步;
- 回声抑制:应用远端写入时置
set_applying_remote标志,防止刚拉下来的行又被捕获推回去; - 同步范围:个人内容(笔记、标签、文件夹、便签、提醒、稍后读、文档、知识单元、剪藏、胶囊、RSS 订阅);团队空间内容不参与同步。
快照保险箱与恢复
- 每个账号最多保留 20 个快照,超出自动删最旧;单个快照上限 50MB;默认保留 90 天,到期在下次上传时清理;
- 恢复(
restore_from_snapshot):拉取云端最新快照 → 用BACKUP_AAD解密 → 走data_transfer_service.import_user_data按 id 合并,新者胜,本地独有记录不删; - 恢复显式落个人空间(
tenant=None):同步是个人通道,不跟随当前激活空间——在团队空间视图下恢复快照不会把行盖成团队行; - 恢复完成后把同步游标锚到快照对应的 op 序号,后续增量从该点继续;
- 暂不提供历史版本浏览;恢复是合并,不是回滚。
云端→桌面明文下行通道
pull_down_cloud 把云端账号下的个人内容(例如网页端写入的笔记)拉回桌面端本地库:下行本来就只发个人行,与应用侧列白名单、回声抑制同一套机制。这条通道让「网页端临时记一条,回到桌面端自然出现」成立。
本地加密保险柜(vault)
保险柜解决的是另一个面:本机磁盘的静态加密(防「别人动我电脑」),与云同步相互独立、可叠加使用。详见本地加密(用户指南)。
- 双层密钥:随机 DEK 加密数据库本体,密码经 scrypt 派生的 KEK 只用于包裹 DEK;改密码只需重包 DEK,即时完成;
- AES-256-GCM + 原子写(先写临时文件再改名),断电不留半个密库;
- 「在这台电脑上记住密码」经 Windows DPAPI 保存 DEK,仅当前系统用户可解;
- 锁定/退出后
psb.db(含 WAL/SHM)整体加密为psb-vault.enc;解锁使用期间工作副本是明文。
桌面端数据目录
| 部署形态 | 数据位置 |
|---|---|
| 安装版 | %APPDATA%\psb-desktop\data\ |
| 便携版 | EXE 同级 data/ 目录(存在即优先,实现整机U盘携带) |
便携版把数据与程序放在同一目录,适合在移动介质上整体带走;代价是不支持自动更新(安装版启动 10 秒及每 6 小时检查更新)。两台设备、两种形态之间,靠上面的 E2EE 同步保持一致。
常见问题口径
- 口令无法找回:口令不参与任何服务端存储,忘记意味着云端密文永久无法解开,只能设新口令重新备份;
- 网页端无此功能:网页版数据本就在云端账号下,不存在「本机→云端」的搬运需求;
- 同步口令 ≠ 登录密码 ≠ 保险柜密码:三者相互独立,建议分别设置并各自牢记。
下一步
- 端到端加密云同步(用户指南):启用、备份与恢复的操作步骤
- 本地加密(保险柜):本机静态加密的开启与锁定
- 云备份与恢复:手动打包备份与导出导入
- 数据源导入与网页抓取:导入服务的空间口径