给单条对话上一把锁:应用层加密与系统解锁各管哪一段

一、锁的位置一变,问题就换了
据公开报道,有对话产品开始逐步为保存的单条对话上锁:用户设一个四位账户 PIN 才能访问,支持指纹或面容解锁的移动设备上也可以用设备自身的解锁方式替代。
先划一条边界:这次报道没有给出加密算法、密钥存放位置,也没有说明服务端能看到什么。在这个前提下,两种说法都不能讲——既不能称它是端到端加密,也不能断言服务端读得到明文。能讨论的是这类功能一旦落到工程上必须回答的四件事:密钥从哪来、忘了怎么办、外面有几份副本、换设备之后还算不算同一把锁。
这四问的分量在于锁的位置变了。设备解锁保护的是”这台机器现在归谁用”,它的粒度是整机,代价是借你手机查个东西都要输密码,于是人们干脆把密码设成免验证。内容级锁把粒度收到”这一条记录”,好处是能只把敏感的那部分关起来,坏处是所有原本由设备承担的假设都不成立了:设备安全不等于内容可读,账户在线不等于你有权限打开那一条。
二、三种密钥模型,给的是三种完全不同的边界
| 密钥模型 | 谁能解开 | 失效面 | 恢复的可能 |
|---|---|---|---|
| 口令派生且密钥不出端 | 只有持有口令的设备;服务端只存密文 | 口令强度决定一切;跨端要重新拿到口令才能解 | 没有恢复路径就没有恢复,忘了就等于永久不可读 |
| 口令派生但服务端保留副本 | 用户,以及任何能取回副本的一方 | 副本所在处成为集中风险点;边界依赖访问控制而非密码学 | 可以恢复,前提是恢复流程本身不被滥用 |
| 纯服务端托管 | 服务方按策略放行 | 安全性取决于账户体系:账户被盗等于锁不存在 | 最顺滑,也最依赖账户找回与风控质量 |
这张表对我们的意义是:同一个”上锁”按钮,放在三种模型里给出的保证完全不同。第一种防的是设备被他人临时使用;第二种和第三种实际防的是”没登录的人”,其强度等于账户安全强度。
系统生物识别属于第四类,它既不是模型也不是托管——它是本机安全芯片对本人的一个断言,解锁的结果通常是把本机保存的密钥放出来。所以”能用 Face ID 或 Touch ID 代替 PIN”这句话,在工程上意味着本机必须存有一份可用凭据;这份凭据的暴露面与那条 PIN 完全不是一回事。同一把锁,在两种解法下对应两种攻击成本,产品文档要写清哪一种是主路径。
顺带一条容易被忽略的:换机或重置设备之后,本机的第二把钥匙没了。这时能否用 PIN 单独打开,直接暴露出密钥实际存放在哪一层——这也是判断某把锁究竟属于表中哪一行的最实用测法。
三、忘记 PIN 这条路,必然带来一次弱化
四位数字,忘掉的概率不低,所以找回流程一定存在;而找回通道就是攻击面,这不是设计缺陷,是这类功能的固有代价。工程上要管住的是三条。
第一,找回的前置条件不能退化成”证明你登录着”。如果解锁某条对话只需要账户会话,那么锁保护的强度就等于账户强度,找回流程只应当验证账户,不该另设第二道宽松的门。合理的做法是给找回加时间冷却与通知:触发即向账户的既有联系渠道告警,并在一段时间内保持敏感动作可见。
第二,找回之后旧密文怎么处理要写明。这里只有三种诚实的选项:旧数据用新密钥重新封装、旧数据作废并明确告知用户、旧数据保持原样但需要原始口令才能再读。写成”重置 PIN”四个字就过去的流程,用户会以为什么都没变,实际可能是加密边界被换了一次。
第三,找回要有次数与留痕。同一账户短期内反复触发找回,是账号被尝试的信号之一;这一条要进风控而不是只进帮助文档。
四、四位 PIN 的强度取决于它旁边的三个机制
算术上,四位数字是有限集合,任何在线可反复尝试的实现都撑不住。所以这类锁的真实强度不在位数,而在三个配套机制上。
限次与递增延迟:连续失败后拉长间隔、缩短可尝试速率。锁定策略:失败到达阈值后不是继续让用户试,而是把解锁降级为”必须先走账户找回”,并明确解除方式。告警:解锁失败与找回触发要能在账户侧看到,用户知道自己被试过,才有下一步动作。
再加一条实现层的:派生口令时要有工作因子足够高的密钥派生过程与每用户不同的盐,否则一旦密文被拿到,四位空间可以被离线穷举。这一段是所有”防在线尝试”的机制在离线场景下失效后的兜底,来源未给出细节,我们无法判断某一家是否这么做,但把它列为评估这类功能时必答的一题。
再补一条密级判据,这条对企业侧比对用户侧更有用。这类锁的实际覆盖面是”设备被身边人翻看””临时会话被旁人扫一眼”这一档风险;合同正文、病历、凭据、客户名册这类材料,它们的威胁模型包括账户被接管、副本被索引、导出被留存,与四位锁根本不在一档。所以正确的处置顺序是先做数据分级,再决定它进不进这类会话,而不是先进了会话再补一把锁。
五、副本清单:一把锁通常覆盖不到的地方
内容级锁最容易失真的一点是:用户锁的是一条对话,系统里存在的是一堆派生物。逐个列出来才知道边界在哪。
| 位置 | 里面留下了什么 | 是否受同一把锁覆盖 | 该做的动作 |
|---|---|---|---|
| 原始记录 | 完整消息序列 | 是,这是锁本体 | 明确锁定的最小单位是会话还是单条 |
| 搜索索引 | 标题、摘要、可命中的片段 | 常常不受,命中即泄露存在性 | 敏感会话不进索引,或索引里只留不可读标识 |
| 通知与预览 | 首行内容或最后一条内容 | 常常不受 | 允许按会话关闭预览文案 |
| 导出包 | 全量文本 | 通常不受,导出即脱离锁 | 导出前二次确认,导出文件带时间戳与来源标识 |
| 备份快照 | 某一时点的完整副本 | 取决于备份是在加密前还是加密后 | 明确备份里是否含已解锁内容,恢复时是否重新加密 |
| 服务端日志与缓存 | 请求参数、中间结果、临时缓存 | 基本不受 | 内容不进日志,缓存有生存期与访问控制 |
六行里最实际的问题是第二行和第三行。锁本身做得再对,搜索命中与通知文案也能把内容说出去。这也是洹拓在给客户做类似功能评审时坚持要的一份”锁的覆盖范围声明”——它能枚举,才算有边界;不能枚举,界面上那个锁图标只表示”打开时需要多按一次”。
六、跨端一致与企业产品的验收清单
多端场景把边界问题放大。网页端能不能解锁、能不能用系统的生物识别替代 PIN、多台设备同时登录时一条会话的锁定状态是不是同一份、换机迁移后 PIN 与本机凭据的关系怎么处理——这四问要有一致的答案,且答案要写在帮助文档里而不是靠试。最糟的设计是”手机能解,网页不能解”或反过来的不对称,因为它会让用户以为自己忘了设置,实际是产品给同一把锁发了两把不同的钥匙。
把这类能力做进企业产品时,验收清单要短而硬。
- 锁的范围可枚举:能明确列出哪些字段与哪些派生物受锁保护,形成上面那张副本表的实际版本。
- 解锁失败原因可区分:口令错、会话失效、记录不存在、被锁定四类要能分别返回,前端的提示与后端的审计口径一致。
- 审计能看到谁解锁过:解锁事件包含主体、设备、时间、结果与来源端;企业侧要能按人或按记录回查。
- 恢复流程的密码学后果写明:是否重置密钥、旧密文如何处置,写进变更说明和对外文档,不做隐含行为。
- 多端状态一致:锁定与解锁在任何一端生效后,其余端在下一次读取时得到同一状态,不出现”一端已解、另一端未知”。
- 覆盖范围变更要通知:新增索引或导出这类派生物时,等同于削弱现有锁的范围,要走变更评审。
第 4 条和第 6 条是我们在做产品安全说明时会逐字写的两句,因为它们决定了客户能不能把这件事写进自己的内控材料。企业客户不会因为你有锁而买单,他们会因为你能说清锁管到哪一段、管不到哪一段,以及管不到的部分怎么处理而签验收单。