All notes

Senvra Backup 技术方案

Senvra Backup 技术方案Senvra Backup 技术方案Senvra Backup 技术方案Senvra Backup 技术方案

Senvra Backup 技术方案

版本:2026-08 范围:Senvra 备份与还原 V1,写入格式以 SNVRBKP3 为准,并保留对 SNVRBKP2 的只读兼容。 目标:让用户可以安全地迁移或长期保存数据,同时避免备份文件、错误提示、交互文案泄露空间身份。

1. 方案概览

Senvra 的备份设计不是简单地把数据库和媒体文件打包导出,而是把备份看作一次独立的加密发布流程。导出时不落地明文临时文件,还原时不直接覆盖空间,而是经过校验、解密、查重、临时导入和原子提交几个阶段。

Flow diagram Preparing diagram
View diagram source
flowchart LR
    A[当前空间数据] --> B[导出清单构建]
    B --> C[逐项读取媒体与元数据]
    C --> D[分块 AES-256-GCM 加密]
    D --> E[SNVRBKP3 流式写入]
    E --> F[原子落盘为 .senvrabackup]

    G[.senvrabackup] --> H[Header 与 AAD 校验]
    H --> I[凭据派生与解密]
    I --> J[中性查重]
    J --> K[临时导入区]
    K --> L[原子提交到当前空间]

核心原则:

原则设计选择
不泄露来源空间外层 Header 禁止写入 sourceSpaceID、scope、backupID 等可识别字段
不暂存明文导出和还原均采用流式处理,明文只存在于内存中的短生命周期缓冲
不跨空间恢复身份还原只支持“导入当前空间”,不展示“备份来自哪个空间”
不信任文件结构Header、Manifest、Note、Attachment、Chunk 都必须被认证和归属校验
不牺牲交互隐私长耗时任务显示中性的 Privacy Shield,避免露出相册内容或空间状态

2. 威胁模型

备份文件通常会被放进 iCloud、移动硬盘、聊天文件、NAS 或第三方网盘,暴露面比 App 沙盒更大。因此备份格式必须假设攻击者可以长期持有 .senvrabackup 文件,并反复进行离线分析。

Mind map Preparing diagram
View diagram source
mindmap
  root((Backup Threat Model))
    离线攻击
      暴力破解密码
      重放旧 Header
      篡改 Manifest
    身份泄露
      空间 ID 暴露
      文件名暴露
      错误提示暴露路径
    数据完整性
      媒体块被替换
      Note 与 Attachment 关系被伪造
      导入中断留下半成品
    体验风险
      长任务期间露出敏感缩略图
      大文件导出卡顿
      低磁盘导致损坏备份

防护重点不是“文件后缀看起来私密”,而是确保备份文件在离线环境下仍然只暴露最少元信息,并且任何篡改都会在解密或导入前被发现。

3. 密钥与凭据模型

Senvra 使用双凭据模型。私密空间以用户保存的 Access Key 为基础,再叠加 Backup Password;公共空间不要求用户理解空间密钥,而是使用随机 Backup Key 来隔离备份加密材料。

Flow diagram Preparing diagram
View diagram source
flowchart TB
    subgraph PrivateSpace[私密空间备份]
        A1[Access Key] --> C1[KDF]
        B1[Backup Password] --> C1
        C1 --> D1[Backup Encryption Key]
    end

    subgraph PublicSpace[公共空间备份]
        A2[Random Backup Key] --> C2[KDF]
        B2[Backup Password 可选/按产品策略] --> C2
        C2 --> D2[Backup Encryption Key]
    end

    D1 --> E[AES-256-GCM 分块加密]
    D2 --> E

推荐实现约束:

项目约束
KDFPBKDF2,默认 600k 迭代,并为后续 Argon2 或更高迭代预留参数字段
数据加密AES-256-GCM
分块大小默认 8 MiB,每块独立 nonce 与 tag
认证数据Header canonical bytes、版本号、chunk index、manifest digest 等纳入 AAD
密钥生命周期派生密钥只在任务内存活,任务取消或失败后立即释放引用

4. SNVRBKP3 文件结构

SNVRBKP3 是当前写入格式。它的关键变化是强化 Header/AAD 认证,并将 Manifest、Note、Attachment 的归属关系纳入导入前校验。

Flow diagram Preparing diagram
View diagram source
flowchart LR
    A[Magic<br/>SNVRBKP] --> B[Version<br/>3]
    B --> C[Header Length]
    C --> D[Public Header]
    D --> E[Salt<br/>KDF Params]
    E --> F[Manifest Digest]
    F --> G[Encrypted Manifest]
    G --> H[Encrypted Chunks]
    H --> I[Final Auth Trailer]

外层 Header 只允许放置解密和兼容所需的中性字段。

允许字段用途
magic识别备份文件类型
version选择解析器和兼容路径
kdf描述 KDF 算法与参数
salt密钥派生随机盐
chunkSize流式解密的块大小
createdAt可选,中性时间信息
禁止字段风险
sourceSpaceID直接泄露来源空间身份
scope / space type暗示用户的私密空间结构
backupID可能被跨文件关联追踪
原始文件名 / 系统路径可能泄露内容语义或设备信息

5. 导出流程

导出流程以“清单先行、流式写入、失败清理”为主线。系统先构建待导出的逻辑清单,再逐项读取数据库记录和媒体文件,边读边加密写入目标文件,不创建明文压缩包。

Sequence diagram Preparing diagram
View diagram source
sequenceDiagram
    participant UI as Backup UI
    participant App as AppModel
    participant Store as VaultStore
    participant Crypto as Crypto Pipeline
    participant File as Backup Writer

    UI->>App: 用户确认导出
    App->>Store: 请求快照与导出清单
    Store-->>App: Notes / Attachments / Media refs
    App->>Crypto: 初始化 KDF 与 Header AAD
    loop 每个媒体或元数据块
        App->>Store: 流式读取
        Store-->>Crypto: 明文缓冲
        Crypto-->>File: 密文块 + tag
    end
    File->>File: fsync + 原子 rename
    App-->>UI: 完成或中性失败信息

性能策略:

场景策略
大媒体文件固定 8 MiB 分块,避免一次性读入内存
大量小附件批量构建清单,减少数据库往返
低磁盘导出前预估空间,导出中监控写入失败并清理临时文件
任务取消停止读取、销毁密钥引用、删除未完成临时备份
App 失活进入中性遮罩,避免任务期间暴露内容缩略图

6. 还原流程

还原不是“恢复一个空间”,而是“把备份内容导入当前空间”。这个产品边界可以避免用户从 UI 文案或数据结构里推断出备份来源空间。

Flow diagram Preparing diagram
View diagram source
flowchart TD
    A[选择 .senvrabackup] --> B{Magic / Version 合法?}
    B -- 否 --> X[中性失败提示]
    B -- 是 --> C[读取 Header 与 KDF 参数]
    C --> D[输入 Access Key / Backup Password]
    D --> E{Header AAD 校验通过?}
    E -- 否 --> X
    E -- 是 --> F[解密 Manifest]
    F --> G{归属关系校验}
    G -- 否 --> X
    G -- 是 --> H[中性查重]
    H --> I[写入临时导入区]
    I --> J{全部块校验通过?}
    J -- 否 --> Y[清理临时导入区]
    J -- 是 --> K[原子提交到当前空间]
    K --> L[完成]

导入前必须完成三类检查:

检查目的
Header/AAD 认证防止攻击者替换版本、KDF 参数或 Header
Manifest digest防止清单被替换、裁剪或重排
Note/Attachment 归属防止附件被挂到错误 Note,或伪造孤儿记录

查重逻辑必须保持中性:可以判断“已存在相同内容”并跳过重复项,但不展示来源空间、原始路径、原始文件名等敏感上下文。

7. Privacy Shield

备份和还原属于长耗时任务。用户一旦进入后台、锁屏、切换 App、触发录屏风险,界面应该切换到中性的 Privacy Shield,而不是继续展示相册网格、文件名或空间状态。

State diagram Preparing diagram
View diagram source
stateDiagram-v2
    [*] --> Idle
    Idle --> Exporting: 开始备份
    Idle --> Importing: 开始导入
    Exporting --> Shielded: App 失活 / 锁屏 / 风险状态
    Importing --> Shielded: App 失活 / 锁屏 / 风险状态
    Shielded --> Exporting: 回到安全前台
    Shielded --> Importing: 回到安全前台
    Exporting --> Finished
    Importing --> Finished
    Exporting --> Failed
    Importing --> Failed
    Failed --> Idle
    Finished --> Idle

界面文案应保持中性,例如:

不推荐推荐
正在恢复私密空间正在导入备份
来自 XXX 空间的备份已恢复已导入可用内容
文件 IMG_0001.mov 解密失败部分内容无法导入
/var/mobile/... 写入失败存储空间不足或文件不可用

8. 原子化与失败恢复

导入流程必须保证“要么全部提交,要么看起来什么都没发生”。用户不应该在失败后看到半张图片、半条 Note 或孤立附件。

Flow diagram Preparing diagram
View diagram source
flowchart LR
    A[创建导入事务] --> B[写临时数据库记录]
    B --> C[写临时媒体文件]
    C --> D[校验所有 tag 与 digest]
    D --> E{校验通过?}
    E -- 是 --> F[批量提交记录]
    F --> G[移动媒体到正式目录]
    G --> H[提交事务]
    E -- 否 --> I[回滚数据库]
    I --> J[删除临时媒体]

失败处理规则:

阶段失败动作
凭据错误不暴露是 Access Key 还是 Password 错,只提示无法打开备份
Header 校验失败停止解析,避免继续读取被篡改结构
分块解密失败删除当前临时文件,标记任务失败
导入提交失败回滚数据库事务,并清理临时媒体目录
用户取消尽快停止 I/O,清理临时产物,界面回到安全状态

9. 兼容策略

Flow diagram Preparing diagram
View diagram source
flowchart LR
    A[SNVRBKP2<br/>只读兼容] --> B[SNVRBKP3<br/>当前写入格式]
    B --> C[Future<br/>新 KDF / 分块索引 / 压缩策略]

兼容原则:

版本策略
SNVRBKP3默认导出格式,完整安全能力
SNVRBKP2只读导入,不再生成
未知更高版本不尝试降级解析,提示当前版本暂不支持
损坏或伪造版本返回中性失败,不展示底层异常

10. 验收红线

上线前至少满足以下红线:

  • 外层 Header 不包含 sourceSpaceID、scope、backupID、原始文件名、系统路径。
  • 导出流程不创建明文 zip、明文 tar、明文 sqlite 副本或可恢复的明文临时目录。
  • SNVRBKP3 的 Header、Manifest、Chunk 均参与认证,任意篡改都能失败。
  • Note 与 Attachment 的归属关系在导入前验证,不能出现跨记录挂载。
  • 还原只能导入当前空间,UI 不出现“恢复到原空间”或“来自某空间”的暗示。
  • 导入提交具备事务边界,失败后不能留下半成品。
  • 低磁盘、强制中断、用户取消后,会清理临时文件。
  • 错误提示不包含文件名、路径、空间名、内部 ID 或系统异常原文。
  • 长耗时任务在失活、锁屏、录屏风险下进入 Privacy Shield。

11. 用户路径

Journey map Preparing diagram
View diagram source
journey
    title 用户备份与迁移体验
    section 导出
      选择备份: 5: 用户
      设置备份密码: 4: 用户
      保存 Access Key 或 Backup Key: 3: 用户
      等待导出完成: 4: 用户
    section 保存
      把 .senvrabackup 放到可信位置: 4: 用户
      记录凭据: 3: 用户
    section 导入
      选择备份文件: 5: 用户
      输入凭据: 3: 用户
      导入当前空间: 5: 用户

体验设计的重点是让用户明确知道两件事:

  1. 备份文件本身已经加密,但丢失凭据就无法恢复。
  2. 还原会导入当前空间,不会在 UI 上暴露备份原本属于哪个空间。

12. 实现检查清单

模块检查项状态
Backup Writer流式写入、原子 rename、失败清理必须
CryptoPBKDF2 参数、AES-GCM chunk、AAD 绑定必须
ManifestDigest、记录归属、版本兼容字段必须
Restore Pipeline临时导入区、查重、事务提交必须
UI中性文案、Privacy Shield、进度反馈必须
Error Boundary过滤系统路径、文件名、内部 ID必须
CompatibilitySNVRBKP2 只读、未知版本拒绝必须
Disk Guard导出/导入前容量预检,失败后清理必须

13. 总结

Senvra 的备份方案核心不是“导出一个文件”,而是把敏感数据从 App 沙盒带到更不可信的外部环境时,仍然保持加密、认证、低泄露和可恢复的工程边界。

这套方案用 SNVRBKP3 解决格式可信问题,用双凭据模型解决离线攻击问题,用流式加密解决明文暂存和大文件性能问题,用当前空间导入与中性文案解决身份泄露问题。最终目标是让备份文件可以长期保存、跨设备迁移,同时不让用户承担理解内部空间结构的成本。

From MonoWare

Senvra has more context behind this note.

Open the product site or keep reading notes filtered to Senvra.

Stay in touch

Product releases and engineering notes, without a tracking-heavy inbox funnel.