全部文章

如何让私密空间的 Access Key 更安全

从创建私密空间后“Access Key 应该放在哪里”的真实困扰出发,介绍 PIN 保护副本和二维码传递方案。

SenvraAccess Key隐私加密二维码
如何让私密空间的 Access Key 更安全

我们在自己使用 Senvra 时,反复遇到一个看似简单的问题:创建私密空间以后,这串能够恢复空间的 Access Key 到底应该放在哪里?

只留在同一台手机上,会削弱它作为恢复凭据的意义;把明文 key 放进邮箱、笔记、密码管理器或另一块磁盘,虽然以后找得到,却也让一个能够打开私密空间的重要凭据出现在更多位置。

真正需要使用时,体验也并不好。用户要先找到保存位置,把 key 复制出来,传到当前手机,再粘贴进 Senvra。整个过程既增加了明文经过剪贴板和其他系统的机会,也让一次本应简单的恢复操作变得繁琐。

正是这个持续出现的真实使用场景,让我们开始重新设计 Access Key 的保存与使用方式。Senvra 的下一个版本会增加两个可选工具:使用独立 6 位 PIN 保护 Access Key 副本,以及使用二维码传递。目标不是把 6 位 PIN 说成高强度密码,而是减少原始 256-bit Access Key 以明文出现的次数,并尽量取消不必要的剪贴板搬运。

问题出现在日常保存和搬运中

在 Senvra 内部,每个私密空间已经由随机 256-bit 主密钥和认证密钥包装保护。本文讨论的薄弱点,发生在用户把 Space Access Key 导出之后。

流程图 正在生成图表

左右滑动查看完整图表

查看图表源代码
flowchart TB
    accTitle: Responsive flowchart
    subgraph R1[" "]
        direction LR
        A[明文 Access Key] --> B[邮箱、笔记或磁盘] --> C[导入当前手机]
    end
    C --> D[访问与恢复]
    C --> E[凭据维护]
    D --> F[打开私密空间]
    D --> G[创建或恢复备份]
    E --> H[重置或更换密码]
    E --> I[轮换 Access Key]
    style R1 fill:transparent,stroke:transparent

因此,Access Key 不只是一串在忘记密码时才会用到的备用文本。它是私密空间的恢复与关键维护凭据:打开私密空间、创建或恢复备份、重置或更换密码,以及轮换 Access Key 本身,都需要它。正因为用途如此关键,它的保存和传递方式也必须被认真设计。

邮件草稿可能同步,笔记可能被索引,剪贴板管理工具可能保留历史,其他 App 也可能在不合适的时机读到粘贴内容。这并不代表 Senvra 内部的本地加密失效,而是恢复凭据离开原本边界后,以明文经过了更多系统。

因此,第一个设计目标很直接:让用户可以保存一份可移动副本,同时不要求原始 Access Key 在所有外部位置都保持可读。

一个可选的 PIN 保护副本

新流程允许用户为 Access Key 副本增加一个独立的 6 位 PIN。原始 Access Key 仍然是均匀随机的 32 字节值。Senvra 生成 16 字节随机 salt,用 PBKDF2-HMAC-SHA256 对 PIN 执行 600,000 次迭代,再通过带独立用途上下文的 HKDF-SHA256 生成 32 字节掩码。

Access Key 字节与这个掩码执行 XOR。便携封装还会加入经过遮蔽的版本头和 0–24 字节随机 padding,再使用自定义 64 字符传输字母表编码。导出的结果不包含邮箱、空间名称、账号标识,也没有可读的 “Senvra Access Key” 标签。

流程图 正在生成图表

左右滑动查看完整图表

查看图表源代码
flowchart TB
    accTitle: Responsive flowchart
    subgraph R1[" "]
        direction LR
        A[Access Key + 独立 PIN] --> B[PBKDF2<br/>600,000 次迭代] --> C[HKDF<br/>32 字节掩码]
    end
    subgraph R2[" "]
        direction RL
        D[XOR + 随机化封装] --> E[保护文本或二维码] --> F[PIN 生成候选 key]
    end
    subgraph R3[" "]
        direction LR
        G[目标私密空间包装] --> H{AES-GCM 能否打开?} --> I[接受或拒绝]
    end
    R1 --> R2
    R2 --> R3
    style R1 fill:transparent,stroke:transparent
    style R2 fill:transparent,stroke:transparent
    style R3 fill:transparent,stroke:transparent

自定义字母表和随机 padding 只是传输层混淆,并不是密码学强度的来源。保护来自 PIN 派生掩码。但 6 位 PIN 只有一百万种组合,所以这个功能只能被描述为降低日常明文暴露风险的附加屏障,不能替代高熵密钥。

为什么保护副本不会直接告诉你“PIN 错了”

最直观的做法,是用认证加密直接加密 Access Key,并通过认证标签判断解密是否成功。这样很方便,但也意味着泄露的保护字符串自带一个 PIN 验证器:攻击者可以逐个尝试 PIN,并立即知道猜测是否正确。

Senvra 刻意不提供这个性质。每个格式正确的 6 位 PIN 都会产生一个外观正常的 32 字节 Access Key 候选值;被修改过的保护字符串也可能产生一个外观正常的候选值。外层保护本身不知道这个候选值是否正确。

判断被推迟到唯一拥有正确上下文的位置:目标私密空间。Senvra 使用候选 Access Key 派生该空间的恢复包装密钥,再尝试打开绑定到该空间身份的 AES-256-GCM 认证主密钥包装。只有这个操作成功,才能证明 Access Key 确实属于该空间。

这意味着:

  • 单独泄露的 protected key 不包含一个自给自足的“PIN 正确”信号。
  • 错误 PIN 不会在外层提前返回有帮助的认证结果,而是生成错误的候选 key。
  • 候选 key 无法打开目标空间的认证主密钥包装时,私密空间才会拒绝它。
  • 如果攻击者同时拿到了目标保险库元数据,这些数据仍可能成为验证目标。因此 6 位 PIN 必须分开保存,也只能被视为有限强度保护。

更高的成本,但不是“不可能暴力破解”

600,000 次 PBKDF2 迭代会让每一次 PIN 猜测都付出明确成本。当攻击者同时拥有目标空间的验证数据时,完整检查全部一百万个 6 位 PIN,最多需要执行一百万次完整派生,也就是按当前参数约 6000 亿次 PBKDF2 配置迭代。相比明文保存或快速哈希,这显著提高了攻击成本,但不能表述为数学意义上的“不可能暴力破解”。

正常使用时,最终验证由 Senvra App 在打开目标私密空间时完成。但真正的密码学要求是拿到目标空间的认证包装数据,而不是依赖一段只有官方 App 才能执行的秘密逻辑。如果攻击者同时得到 protected key 和目标保险库元数据,仍可能自行实现等价的离线验证器;如果只泄露 protected key,则无法仅凭这段字符串确认某个 PIN 是否正确。这也是 protected key 与 PIN 必须分开保存的原因。

我们选择的是一个更窄、但更诚实的安全属性,而不是宣称短 PIN 等同于强密码。

二维码减少搬运,但不会让 key 变成公开信息

下一版本还允许把 Access Key 副本显示并保存为二维码。在另一台设备上,Senvra 可以用摄像头扫描,或从用户选中的图片中读取,并在本地填入 Access Key。

这样可以减少多次复制和粘贴。用户可以把 protected key 的二维码保存在自己选择的位置,需要时直接扫描,再输入单独保存的 PIN。保护字符串和二维码承载的是同一份材料;二维码是传输形式,不是额外的加密层。

安全规则仍然很简单:任何能扫描或保存二维码图片的人,都能复制其中的内容。明文 Access Key 二维码必须像明文 key 一样保护。更稳妥的方式是保存受 PIN 保护的二维码,并把 6 位 PIN 放在另一个位置。

Senvra 也会限制输入范围:扫描器只接受规范化的明文 Access Key 或合法的 protected envelope,拒绝任意 URL 和无关二维码,限制导入图片大小,并在 App 离开活跃状态时清除尚未完成的 PIN 输入。

旧 key 不需要更换

保护副本改变的是 Access Key 的保存和传输方式,不会轮换私密空间底层的 Access Key。已有明文 key 继续兼容。

在下一个版本中,用户可以:

  1. 在新建私密空间时,先把新生成的 Access Key 转成 PIN 保护副本再保存。
  2. Security → Password & Access Key 中,本地转换已有明文 Access Key。
  3. 把结果保存为文本或二维码图片。
  4. 以后通过扫描或粘贴导入,再输入独立的 6 位 PIN。
  5. 在确有需要时,明确切回明文表示。

转换工具不会把 key 加入其他空间,也不会上传。生成保护副本后,Senvra 会从该工具的临时界面状态中清除明文 key 和 PIN。

实际的安全使用方式

这个功能是在减少暴露面,不是在消除用户的保管责任。

请把 protected key 与 PIN 分开保存。不要因为邮箱、相册或笔记使用方便,就默认它们是私密存储。确认保护副本能够使用后,再删除旧的明文副本。真正依赖它之前,先完成一次恢复测试。还要记住:如果可用的 Access Key 和密码同时丢失,私密空间仍然无法恢复;Senvra 没有服务器端恢复后门。

关于更完整的密钥模型,可以阅读为什么 Senvra 换密码不用重新加密所有照片?

这次即将发布的更新,把过去只有明文的恢复流程变成了一个明确选择:需要兼容时继续使用原始格式;更在意减少明文暴露时,则使用独立 PIN 和二维码传递。

来自 MonoWare

Senvra 背后还有更多上下文。

打开产品网站,或继续阅读按 Senvra 筛选的笔记。

通讯

隐私与产品工程笔记,偶尔发送。