只读分享解决方案文档原理方案设计📅 2026-10-14🔖 Rev 1.0⏳ 还有3日到期
🔧解决方案&应用市场分析 -> 原理方案设计 -> 电子设计&技术探讨 -> 安全擦除与RPMB安全启动链路_技术探讨

安全擦除与RPMB安全启动链路_技术探讨

同系列 · 原理方案设计
扫码打开本页
微信扫码

安全擦除、RPMB 与安全启动链路 · 技术探讨

把「数据删干净」「计数不可回退」「代码不可篡改」「根不可伪造」这四件事接成一条链 —— 一份面向嵌入式存储安全的通用原理篇 | 编制日期 2026-10-14 | 版本号 Rev 1.0

结论: 安全擦除、RPMB、安全启动不是三个并列的功能,而是同一条信任链上的四个环节。 安全擦除管的是「密钥没了就等于数据没了」,RPMB 管的是「计数不可回退」, 安全启动管的是「代码不可篡改」,密钥管理管的是「根不可伪造」。 四个环节缺任何一环,整条链就断在那里 —— 而且断掉的那一环决定了前面所有努力的实际价值。

4 环节
信任链的组成
安全擦除 · RPMB · 安全启动 · 密钥管理
3 条
安全边界
器件内部 · 控制器 · 主机软件
3 类
被保护的资产
身份凭据 · 固件代码 · 用户数据
1 条
最危险的操作
RPMB 写失败后的盲目重试
2 分
RPMB 的职责边界
防篡改,不防偷看
17 图
机制示意图
时序 · 帧结构 · 状态机 · 决策树

报告总结

存储安全这件事,实践里最常见的问题不是「不会做」,而是做错半步:把覆盖写入当成安全擦除、把加密存储当成防篡改、把签名校验当成固件不可篡改。这些做法单独看都不算错,但它们各自只覆盖了整条链的一段,缺的那一段往往决定了整套方案的实际强度。

这份文档要做四件事:

  • 把四个环节接成一条链。安全擦除、RPMB、安全启动、密钥管理不是四个可选功能,而是四个必须同时成立的环节。任何一环缺失,攻击者都不需要攻破其余三环。
  • 把三个高频误解讲透。安全擦除不等于覆盖写入、不等于 TRIM;RPMB 是有认证的存储而不是加密存储;做了签名校验但固件区可写,等于没做。
  • 把「谁在验证、验证什么、结果放哪」分成三个正交维度。这三个维度混写是绝大多数方案评审文档说不清问题的根源,也是本文反复强调的口径。
  • 把故障处置写成可执行的流程。尤其是 RPMB 写失败之后的处置顺序 —— 这是本领域最容易造成不可逆损坏的一类操作。

覆盖范围以 eMMC / UFS / SD 卡的 RPMB 机制为主,同时给出 SPI NAND、带安全子系统的 MCU 以及其他存储介质的等价机制对照(见附录 A)。本文只讲机制与责任划分,不给寄存器地址、位域位置与具体指令数值,器件级参数一律以正式 datasheet 与规范为准。

读者路径

  • 第一次系统接触存储安全:按第 1 → 2 章顺序读,先把「哪些数据要保护」和「谁负责什么」立住,这是后面所有讨论的前提。
  • 要实现安全擦除:直接看第 3 章(三种擦除手段的适用边界)与第 4 章(密钥层级与删除即销毁),这两章是本文最核心的部分。
  • 要用 RPMB 做防篡改或回滚保护:第 5、6 章是重点,尤其 6.4 与 6.5 两节讲清楚了「为什么盲目重试危险」和「必须先认证读回计数」。
  • 要做安全启动:第 7、8 章,讲信任链传递与存储布局的耦合关系,核心判断标准是固件区是否真的不可写。
  • 要做量产与密钥治理:第 9、10 章,讲凭据注入、派生树、轮换与迁移期双密钥并存。
  • 要做攻击面评审或现场排障:第 11、12 章 + 附录 C 的排查决策树,可当手册直接翻。

1. 存储侧的安全需求从哪里来

存储侧的安全需求不是从「数据很重要」推出来的,而是从「攻击者拿到介质之后能做什么」推出来的。这一章把需求拆成可判断的三类资产、一个可量化的威胁模型,以及介质在整体攻击面中的确切位置。

三类资产最终都落在同一层:介质本身。上层做得再多,这一层失守就全部归零① 被保护的三类资产身份凭据设备唯一密钥、认证密钥证书与信任链材料泄露即设备被克隆固件代码引导代码、固件镜像配置与校准数据被改即行为被改用户数据业务数据、用户凭据日志与诊断记录泄露即合规风险② 攻击者能触碰到的四层,越往下越难阻止物理层拆封、显微读取、直接把介质拿走离线分析接口层监听总线、抓取命令、注入伪造响应协议层复现握手流程、构造非法请求与非法状态存储层内容以明文或弱保护形式长期留存在介质上存储层是唯一「攻击者可以带走、反复离线分析」的一层。上层接口再严密,介质一旦脱离设备控制,分析就完全在攻击者手里进行。因此本文讨论的所有机制,最终都要回答同一个问题:介质上的内容,在攻击者拿到介质之后是否还可用。
图 1 · 三类资产与攻击者能触碰到的四层

1.1 数据分类:哪些数据丢了要出事

「数据要保护」是一句无法指导设计的话。真正能指导设计的是一个二分问题:这份数据丢了或者外泄了,会不会产生不可逆的损失。按这个问题切分,能得到四个格子,而不是笼统的「重要数据」一类。

第一个维度是外泄之后是否要出事,第二个维度是丢了之后能不能重新生成。两者交叉之后:

  • 不可外泄且不可重建——设备唯一密钥、用户口令派生材料。这一格是真正的硬需求,任何妥协都会直接导致设备被克隆或用户身份被仿冒。
  • 不可外泄但可重建——固件镜像、配置模板。泄露不直接造成损失,但会显著降低后续攻击的成本,仍然要保护,只是优先级可以靠后。
  • 不可篡改但可重建——固件代码、启动配置。这是本文第 7、8 章的主题:数据可以被公开,但一旦能被改就失去了所有安全意义。
  • 可丢失——缓存、临时文件、加速数据。只影响体验,不产生不可逆损失,用常规可靠性手段即可。

这个分类的实用价值在于:它能直接回答「这块数据该用哪种机制」。不可外泄且不可重建的走密钥保护,不可篡改的走认证与完整性,不可外泄可重建的走签名加调试口锁定——机制选错的根源往往是分类没做,直接把所有数据一把梭用同一种加密处理。

分类典型内容出事的具体表现能否重建对应手段
不可外泄 · 不可重建设备唯一密钥、认证密钥、口令派生材料攻击者可离线克隆设备或冒充用户不能密钥受保护存放 + 密码学擦除
不可外泄 · 可重建固件镜像、配置模板泄露后协议细节与实现思路被还原能签名 + 调试口锁定
不可篡改 · 可重建固件代码、引导代码、启动配置被改后开机即执行攻击者植入的逻辑能完整性校验 + 固件区不可写
不可篡改 · 不可重建审计日志、计数记录、授权凭据被改后看不出异常操作痕迹不能带认证的存储区(RPMB 等)
可丢失 · 可重建缓存、临时文件、加速数据只影响体验,无不可逆损失能常规删除即可
可丢失 · 不可重建用户业务数据、采集内容造成用户损失但不产生安全风险不能常规可靠性与备份手段
分类的真正用途:把「要不要保护」的争论变成可判定的流程

实践中最耗时间的不是实现机制,而是反复争论某块数据「到底要不要加密」。用上面这张表当判定模板,讨论会快很多:先问能不能重新生成,再问被拿到会不会造成不可逆损失,两个答案一填,机制就定了。填完还拿不准的,通常是因为「重建成本」这一项没有定量——这时按「重建需要产线介入且成本高」的保守假设处理即可。

1.2 三类资产:身份凭据、固件代码、用户数据

把上面的分类再按「谁拥有它」聚合,得到三类资产。这三类的保护目标完全不同,混用手段是方案层面最常见的错误:

  • 身份凭据——设备唯一密钥、RPMB 认证密钥、证书、用户口令的派生材料。保护目标是不可被复制。一旦被复制,攻击者不需要破解任何东西,直接克隆出一台「合法」设备即可。这是最不容妥协的一类。
  • 固件代码——引导代码、固件镜像、配置与校准数据。保护目标是不可被改变。固件本来就是公开的(很多设备甚至公开源码),所以它的安全不依赖保密,而依赖「改不动」。
  • 用户数据——业务数据、用户凭据、日志与诊断记录。保护目标是不可被读取。这一类与前两类的关键差别在于:数据量可能很大、生命周期各不相同,因此不能一把钥匙管到底,必须逐文件或逐对象管理密钥。

把三者放在一起看,会发现一个重要结论:身份凭据与固件代码的体量都很小,可以放进受保护的硬件区域;用户数据的体量大且持续增长,只能靠密钥管理来保护内容本身。这个体量差异,直接决定了后面「密码学擦除」这一整套方法论的位置——它是大体量数据唯一能落地的保护方式。

维度身份凭据固件代码用户数据
核心目标不可被复制不可被改变不可被读取
被破坏后的表现设备可被克隆或身份被冒用设备行为被攻击者控制隐私泄露与合规风险
能否重新生成不能,丢了就是永久丢失能,靠发布与烧录流程不能
需要的保护属性机密性 + 不可导出性完整性 + 来源可验证机密性
体量特征很小,可放进受保护区较小,但含代码与资源大且持续增长
失效的最常见原因密钥与数据同域存放固件区其实可写只做了覆盖写入就当作擦除
本文对应章节第 6 章、第 9 章第 7 章、第 8 章第 3 章、第 4 章

1.3 提取攻击与离线暴力破解的威胁模型

存储侧面对的攻击可以粗略归成两类,它们的边界条件完全不同,防御思路也完全不同。

提取攻击的核心是「拿到介质」:攻击者通过拆机、加热、显微操作或直接获得废弃器件,把存储芯片或卡取出后离线分析。这类攻击的边界是物理能力与成本,它不受任何软件限制,也不受重试次数限制。

离线暴力破解的核心是「拿到密文」:攻击者从介质上读出一堆看起来是密文的数据,然后在自己的设备上无限制地尝试密钥,直到解出明文。这类攻击的边界是算力与密钥强度。它的可怕之处在于「无限制」——设备侧的任何「限制尝试次数」在这一层完全无效。

一个必须刻在脑子里的区别:限速只在设备在线时有效

「连续失败 N 次就擦除设备」这类设计,对在线猜测有效,对离线破解完全无效——因为离线时介质已经在攻击者手里,擦除的是他自己手上的数据。所以真正的防线只有两条:让密钥拿不到(受保护存放 + 派生分散),以及让密钥本身足够强。这两条之外的所有努力,都是在延缓而不是阻止。

按能力把攻击者分档,有助于判断某项防御是否值得投入。下表给出四个典型档位,以及每一档攻击者在物理层之上「拿不到什么」——这才是设计防御时真正该瞄准的地方。

档位典型手段能做到什么拿不到什么应有的最低防线
消费级常规读卡设备、拆机、废弃件读出可读区域与明文数据熔丝状态、器件内部密钥密码学擦除 + 固件区写保护
实验室级专用读写器、逻辑分析仪、抓包复现协议流程、观测密钥协商不可导出的根密钥认证存储区 + 安全启动
专业级热修改、探针卡、故障注入绕过部分状态检查、观测片内总线单向计数器与已熔断的熔丝控制器内完成认证 + 熔丝锁定
系统性投入长期定向研究、定制手段积累的后门、侧信道与长期观测数据理论上没有拿不到的东西分层防护 + 定期轮换 + 缩短暴露期

这张表的实际用法是反向确认:从自己产品当前状态的最高一档往下看,如果某一档的「应有最低防线」在自己的产品里是空的,那就是一个待补的缺口,而不是一个「暂时用不上」的高配项。最后一档永远防不住,所以设计目标不是「不可战胜」,而是把每一档的成本都抬高到不值得。

1.4 存储在攻击面中的位置

把一次攻击拆成四层来看,存储层的位置非常特殊:它是唯一一个攻击者可以完整带走、并且可以无限次离线分析的层。

物理层、接口层、协议层的攻击都发生在设备仍然受控的场合——它们可以被限速、被检测、被拒绝,甚至可以在检测到之后主动销毁数据。而一旦介质脱离设备,攻击者就获得了完整的时间优势与算力优势:可以慢慢试、可以反复解剖、可以对比同一批次的多个样本。此时任何依赖「设备在线时状态」的防御都失效。

这解释了为什么很多传统安全设计在嵌入式存储上不适用:在服务器场景里,「检测到异常就擦除数据」是一种有效策略,因为攻击者必须持续在线;在嵌入式设备里,介质会被直接拿走,这条策略的价值大幅下降。

层次攻击者能做什么存储层能否提供防护说明
物理层拆封、显微读取、把介质带走离线分析能,但代价最高这一层失守后,所有上层机制同时失效
接口层监听总线、抓取命令、注入伪造响应部分能只保护经由器件完成的访问,管不到物理直读
协议层复现握手流程、构造非法请求与非法状态能认证与计数的强度决定这一层的天花板
主机软件层调用合法接口、传合法参数做非法事基本不能合法调用不等于合法用途,要靠主机侧策略补

1.5 存储安全不等于接口安全

「传输通道是加密的,所以数据是安全的」是硬件项目里非常常见的一句想当然。这句话混淆了两个完全正交的保护对象:

接口安全保护的是传输过程——数据在总线上跑的那一刻有没有被监听、截获、替换。它由协议层机制承担,与介质上留着什么没有任何关系。存储安全保护的是静态留存——数据落在介质上之后,攻击者拿到介质能不能读出来。它由器件与主机侧机制承担,与传输时是否加密也没有必然关系。

两种组合都有明确的失效场景:

  • 只做接口安全:传输过程看不出问题,但攻击者一旦拆机读介质,所有内容一览无余。对于「攻击者能接触物理设备」的产品,这等于没有保护。
  • 只做存储安全:介质上的内容确实不可读,但攻击者可以在传输过程中替换、注入、伪造后续的响应——比如在设备请求认证时返回一个「通过」的结果。对协议状态机有篡改能力的攻击者,这比破解密文便宜得多。

正确的判断标准是:先问攻击者最可能走哪条路,再决定在哪一层投入。产品会出厂到客户手上,物理接触几乎必然发生,那么存储安全是底线;如果产品还暴露在不可信网络上被直接访问,那么接口安全同样不能省。两者不是二选一。

维度存储安全接口安全
保护对象介质上长期留存的静态内容传输过程中的数据
典型失效场景介质被拿走、拆解、离线分析链路被监听、被中间人篡改
常见手段密码学擦除、认证存储区、分区权限通道加密、消息认证、重放保护
覆盖不到的地方主机运行时内存中的明文介质上已经落盘的旧内容
失效后的补救无法补救,只能重建设备身份可以靠密钥轮换与通道重建恢复
典型误解以为加密了就不用管删除的事以为链路安全就等于数据安全

1.6 本文要回答的问题与主线

综合前五节,存储侧的安全需求可以收敛成五个问题。本文按这五个问题的顺序推进,章节与问题的对应关系如下:

  1. 哪些数据必须保护,用什么属性保护?(第 1 章)——先做分类,避免机制选错。
  2. 谁负责验证,验证结果放在哪里?(第 2 章)——把器件、控制器、主机三层的责任边界划清。
  3. 数据删掉之后怎么才能保证不可恢复?(第 3、4 章)——三种擦除手段的适用边界,以及密码学擦除的工程实现。
  4. 计数与版本怎么保证不回退?(第 5、6 章)——RPMB 的认证模型、帧结构、计数语义,以及最危险的写失败处置。
  5. 代码怎么保证不被改、根密钥怎么保证不被伪造?(第 7~10 章)——信任链、存储布局、主机侧凭据治理与轮换。

这五个问题串起来就是本文的主线:一条从根密钥到用户数据的信任链。链条的起点是「根密钥不可伪造」(第 7、9 章),中间是「代码不可篡改」(第 7、8 章)和「计数不可回退」(第 5、6 章),终点是「密钥没了就等于数据没了」(第 3、4 章)。任何一环断开,链条的强度就等于最弱那一环,而不是最强那一环。

本文的三条共识,也是阅读时反复对照的主线
  • 安全擦除不等于覆盖写入,也不等于 TRIM。密码学擦除的强度来自「密钥被销毁」,而不是「数据被抹掉」——这是本文第 3 章要讲透的第一件事。
  • RPMB 是有认证的存储,不是加密存储。它防篡改、防重放,不防偷看。把这两件事分清,才不会在方案评审时既高估又低估它。
  • 安全启动与存储的耦合点在「不可写」。固件区的写保护强度决定整条链的强度;只做签名校验但固件区可写,等于没做。

2. 三条安全边界与责任划分

安全不是一件事,而是三件层次完全不同的事各自的承诺。器件内部、控制器、主机软件各自只能对「自己能验证的东西」负责——本章把三条边界划清,并给出一个反复使用的三维描述口径。

三条边界:每层承诺什么,以及明确不承诺什么边界一 · 器件内部能做· 内容离开芯片前完成认证· 一次性位只能由未置位变为已置位· 内部密钥参与运算不经总线输出不做· 不限制主机拿到数据后怎么用· 不判断上层策略是否合理边界二 · 控制器能做· 按分区或按块判定访问权限· 认证通过才更新受保护区域· 受保护计数单调递增不可回退不做· 不判断主机的重试策略是否安全· 不判断主机是否用对了数据边界三 · 主机软件能做· 按用途派生密钥并及时清除中间量· 删除文件时同步销毁对应密钥· 按顺序校验并拒绝不合格镜像不做· 不阻止攻击者持有整机· 不阻止生产流程被动手脚信任自左向右传递:器件内部 → 控制器 → 主机软件每层只对「自己能验证的东西」负责:器件内部验证内容真伪,控制器验证访问者身份,主机验证策略是否正确。把某一层该做的事推给另一层,是最常见的责任错配,第 2.5 节按六种典型场景展开。三层的共同点:都不能防住「攻击者拿着完好设备慢慢试」。这个缺口只能靠密钥轮换、熔丝锁定与流程管控补上。具体能力项以所用器件的正式 datasheet 与安全白皮书为准,本文只描述机制层面的责任划分。
图 2 · 三条安全边界与各自的责任范围

本章最重要的工具不是那几个表格,而是最后那三个维度。讨论任何一项安全机制时,都应该先问三个问题:谁在验证、验证的是什么、验证结果放在哪里。这三个维度互相正交,混在一起说就会得出「器件做了完整性校验」这种既不知道谁做、也不知道校验什么的糊涂结论。

  • 谁在验证——器件内部(阵列与一次性区)、控制器(逻辑块与状态机)、主机软件(应用与引导代码)。三者的可信任程度依次递减,可被篡改的入口依次递增。
  • 验证什么——完整性(内容没被改)、真实性(内容确实来自持有密钥的一方)、新鲜性(内容不比上次旧)。三者对应三种不同的机制,经常被笼统地混称为「校验」。
  • 验证结果放哪——熔丝或一次性位(不可逆)、受保护存储区或单调计数器(可读可增)、普通可写分区(可被改,只有参考价值)。这一项决定验证结果到底算不算数。

2.1 器件内部边界

器件内部边界指的是介质自身提供的、脱离任何外部控制也无法绕过的那些保证。它是整条链里强度最高的一层,因为攻击者要绕过它必须做物理破坏,而物理破坏同时也会销毁他想要的数据。

这一层能提供的保证有四类:内容认证(只有通过了认证的请求才会改变受保护区域)、不可逆状态位(只能由未置位变为已置位,无法恢复)、密钥不外流(密钥在芯片内参与运算,不通过外部总线输出明文)、以及单调计数(某些区域提供的计数器只能递增)。

这一层明确不保证的事情同样重要:它不关心数据取出去之后被怎么使用,不判断上层的策略是否合理,也不保证上层会在正确时机使用这些机制。器件提供能力,策略由主机决定——这是边界的一句话总结。

项目器件能保证的器件不能保证的
内容认证通过认证的请求才会被接受上层是否发出了正确的认证请求
一次性位只能由未置位变为已置位,不可逆是否在正确的时机置位
根密钥密钥在芯片内参与运算,不经总线输出芯片被物理攻击时的安全性上限
单调计数受保护计数器只能递增不可回退计数被读出之后如何决策
失败日志记录认证失败次数并允许上层读取上层是否据此做出正确响应
边界位置在数据离开芯片之前数据离开芯片之后全部失效

2.2 控制器边界

控制器边界指的是器件内部控制器对主机侧暴露的那一层行为约束。它比器件内部边界弱(因为它要处理来自不可信主机的请求),但覆盖范围更广(它管的是整个逻辑块视图,而不只是某一个区域)。

这一层的典型能力包括:按分区或按块的访问权限判定(哪些区域主机可以写、哪些只读、哪些根本不可见)、认证写(受保护区域只接受通过认证的写请求)、请求格式与状态机检查(拒绝非法状态转换)、以及受保护的计数器与序列号。

它不保证的是策略层面的正确性。举个最能说明问题的例子:写失败之后重试是最自然的应用层行为,但控制器只能告诉你「失败了」,重试是否安全完全由主机判断。把这个判断推给控制器的设计,等于把整条链的强度交给了控制器作者。

项目控制器能保证的控制器不能保证的
访问控制按分区或按块判定读写权限主机是否自觉遵守权限约定
认证写认证通过才更新受保护区域认证所用的密钥是否已经泄露
状态机检查拒绝非法状态转换与格式错误的请求上层状态机本身是否设计正确
计数与序列拒绝计数不匹配的请求与重复序列重试策略是否安全
读保护受保护数据只能通过认证读取读出之后如何保管与使用
边界位置在主机命令与介质访问之间主机应用侧与物理接口侧都管不到

2.3 主机软件边界

主机软件边界指的是运行在主控上的代码所能提供的保证,包括引导代码、驱动、文件系统与应用。它的特点是灵活但可信度最低——它运行在攻击者最终一定能够接触到的设备上,任何「只有生产时才存在」的假设都不成立。

这一层实际承担的工作量最大:密钥派生(把根密钥按用途展开成每一份数据对应的密钥)、擦除策略(决定什么时候销毁哪把密钥)、启动校验顺序(决定先验什么后验什么)、凭据生命周期管理(生成、注入、备份、轮换、销毁)、以及故障处置(认证失败时停止还是重试)。

它不保证的也很有代表性:不保证攻击者拿着完好设备慢慢试的时候能被挡住。主机侧能做的是缩短暴露时间、提供可观测性、并配合熔丝与派生树把「拿到一台设备」和「拿到所有设备的根密钥」彻底分开。

项目主机能保证的主机不能保证的
密钥派生按用途派生并在使用后清除中间量派生算法内部是否已被攻破
擦除策略删除文件时同步销毁对应密钥介质物理层面是否仍有残留
启动校验按顺序校验并拒绝不合格镜像不可写区域是否真的不可写
凭据治理保证每台设备的凭据唯一且可追溯生产流程本身是否被动手脚
故障处置识别认证失败并停止危险的自动重试硬件是否已被物理破坏
边界位置在应用逻辑与控制器命令之间对持有整机的攻击者几乎无约束力

2.4 三层各自能保证什么

把三层的保证按前面说的三个正交维度摊开,会得到一张比「三层能力表」更有用的矩阵。这张矩阵的价值在于:任何一个安全特性,都能在这张表里找到它唯一的、不可替代的位置。找不到位置的特性,通常说明它的必要性存疑。

举三个具体例子说明怎么用这张表定位问题:

  • 「我们要不要上 RPMB?」——查第一行。RPMB 的验证者是控制器,验证的是真实性与新鲜性,结果放在受保护计数上。如果需求只是「防止内容被改」,那需要一个验证完整性且结果放在不可篡改位置的东西,RPMB 只是其中一种实现。
  • 「固件区设成只读能不能算安全?」——查第三行与第三列。主机软件层的验证结果放在普通可写分区里只有参考价值,因为攻击者改的往往就是那一区。所以「只读」必须由控制器或器件层面的权限来保证,而不是靠上层不写。
  • 「密钥派生能不能放在控制器里做?」——可以,但派生算法与输入一旦在控制器里,就要接受控制器安全等级的约束。放在主机侧做,算法可以更快迭代,但主机侧本身不可信。这个取舍属于架构决策,不属于机制细节。
验证者验证什么验证结果放在哪覆盖不到的
器件内部内容是否由持有密钥的一方产生一次性位或熔丝(不可逆)内容被取走之后的使用
控制器访问者是否持有密钥、计数是否匹配受保护存储区与单调计数器主机侧的策略是否正确
主机软件策略是否被遵守、顺序是否正确受保护分区、熔丝、日志告警物理攻击与生产流程绕过
「验证结果放哪」是最容易被忽略、也最致命的一维

一个常见的设计错误是:主机软件校验通过之后,把「已通过」这个标志写进一个普通可写分区,然后后续流程信任这个标志。这个设计的问题不在于校验逻辑,而在于标志的存放位置与攻击者的能力不匹配——如果攻击者能改那块分区,他就能把失败改成通过。

判断标准很简单:验证结果存放位置的写权限,必须不劣于被验证对象本身。被验证对象在只读区,结果也必须在不可写或受保护的位置;结果在可写区,就等于没有验证。

2.5 责任错配的典型后果

把某一层该做的事推给另一层,就叫责任错配。它的共同特征是:每一层单独看都在正常工作,合起来却留了一个谁都没管的缺口。下面六种是实践中最常遇到的。

错配典型想法实际后果
把完整性寄托在加密上数据加密了就没人能改密文可被任意篡改,解密后得到被改过的内容
把认证寄托在签名上验签通过就说明固件是好的固件区可写时,攻击者直接改代码绕过验签
把权限寄托在主机上主机不主动写就不用管权限任何能发命令的一方都能读受保护数据
把计数寄托在重试上失败就重试,总有一次会成功写计数已被推进,重试永远对不上
把安全寄托在内存清零上运行时清零就安全了内存内容可被转储,密钥仍会外泄
把产线安全寄托在流程流程上没人会破坏它凭据被批量复制到多台设备

这六种错配里,第四种(把计数寄托在重试)后果最不可逆,因为它破坏的是单调性——而单调性一旦被破坏,无法通过后续操作恢复。第 6.4 节会用一整节讲这件事,本章只强调一点:凡是带计数或序列的机制,都必须先明确「失败之后该做什么」,而不是留到现场再决定。

另外值得注意的是,表格里最后两种(内存清零、产线流程)都属于「攻击成本低、后果严重」的类别。它们的共同点是:防护措施看起来做了,实施过程却完全不受控。安全属性的强度等于最弱的那个执行环节,而不是设计文档上写的那个值。

2.6 威胁模型到机制的对照

本章最后把前面所有讨论压缩成一张对照表:每一条威胁,写清它在第几层被挡、谁去挡、验证的是什么属性、结果存在哪。这张表也是后续各章的索引——第 3 章讲表中的「介质被提取后离线分析」一行,第 5、6 章讲「事务重放」与「版本回滚」两行,第 7、8 章讲「代码篡改」与「根密钥伪造」两行。

威胁在哪一层被挡机制验证的属性结果存放位置
介质被提取后离线分析器件内部 + 主机软件密码学擦除 + 密钥受保护存放机密性(密钥是否可得)受保护密钥区
密钥被离线暴力破解主机软件强密钥派生 + 每文件密钥分散机密性(密钥是否够强)密钥版本与派生树
固件代码被篡改控制器 + 主机软件固件区不可写 + 签名校验完整性 + 真实性不可写分区
旧版本镜像被回滚器件内部 + 控制器版本计数器(熔丝或受保护计数)新鲜性(版本是否更新)熔丝位或单调计数
认证事务被重放控制器认证帧 + 序号 + 随机数新鲜性(是否本次会话)受保护计数
根密钥被伪造器件内部一次性可编程的信任根真实性(是否官方产出)熔丝 / 一次性区
密钥泄露后被长期复用全链轮换 + 版本迁移 + 双密钥并存新鲜性(密钥版本是否最新)密钥版本号

请注意最后三行的共同特征:它们验证的都是新鲜性。新鲜性无法靠「算得对不对」来保证,只能靠不可回退的存储状态来保证——这就是第 5、6 章要用整整两章篇幅讲 RPMB 的原因。对于嵌入式设备而言,「上一次的状态」必须存在一个攻击者改不回去的地方,否则所有版本判断、计数判断、重放判断都只是应用层的一个变量,随时可以被改。

3. 安全擦除:让数据真正不可恢复

这一章要纠正本文的第一个高频误解:安全擦除不等于覆盖写入,也不等于 TRIM。三种手段都能让数据「看起来没了」,但只有一种能让攻击者即使拿到整颗介质也读不出来。

同样叫「删除」,四种手段留下的东西完全不同常规删除只改元数据数据块原样保留读工具可直接还原对抗提取:无效覆盖写入写新内容盖旧内容旧内容未必真消失日志与副本仍在对抗提取:很弱TRIM 通知标记块可回收回收时机由器件定物理擦除可能延迟对抗提取:不足密码学擦除只销毁密钥数据本体保持不动无密钥即不可读对抗提取:有效同一份数据,四种手段之后的可恢复性拿到介质后能否直接读出原文常规删除:能覆盖写入后能否还原覆盖写入:多数场景能TRIM 回收前能否读出TRIM:回收前能密码学擦除后能否读出密码学擦除:几乎不能结论条形越短表示越难恢复。前三种都在「处理数据本体」,只有第四种在「处理密钥」——这就是它们的本质差别。
图 3 · 四种删除手段的残留与可恢复性对比

3.1 常规删除为什么留着痕迹

文件系统里的删除,绝大多数情况下只做了两件事:把文件占用的块标记为空闲,把目录项标记为无效。从物理层面看,数据块里的每一个比特都还留在原地,一个都没变。

这不是实现缺陷,而是有意为之的设计。原因很直接:真正的数据搬运代价很高。在闪存介质上,一次「读出旧块 → 写入新块 → 标记旧块空闲」的完整回收可能带来数百微秒到毫秒级的延迟,还伴随写放大。如果每次删除小文件都做完整回收,删除操作的性能就无法接受。

由此产生两个直接后果:

  • 数据可以通过读工具直接还原。只要拿到介质(或者能访问它的接口),跳过文件系统直接读物理块,就能看到完整的原内容。对攻击者来说这几乎是零门槛的操作。
  • 文件系统自身也可能泄露结构信息。目录树、文件名、分配表、访问时间戳这些元数据即使在「删除」之后仍可能残留,进一步降低攻击者的分析成本。

因此,「文件删掉了」在安全语境下是一句几乎没有信息量的话。真正要问的是:删掉之后,那份数据在介质上还能不能被读出来。

删除动作物理层面发生了什么数据可否被还原残留物
删除文件目录项失效、块被标记空闲可以,读物理块即得原文数据本体 + 元数据片段
清空回收站标记删除,但块通常未回收可以,回收站清空不等于回收数据本体仍在
文件系统格式化重建元数据结构可以,格式化通常不覆盖数据区数据区内容基本完整
整盘覆写为零逐块写入固定模式多数场景可以,取决于覆盖是否彻底磨损均衡可能映射到旧块
删除分区表分区索引被清除可以,未触及数据区数据区全部保留
低层物理擦除擦除单元被真实擦除不可还原(理想情况下)仅剩器件内部的残余电荷分布

3.2 覆盖写入的真实效果与局限

覆盖写入的思路很直白:在旧数据的位置上写入新内容,理论上旧内容就被「盖掉」了。这个思路在机械介质上曾经是标准做法,但在闪存介质上存在四个层次不同的问题。

第一,闪存不能原地覆盖。闪存的物理特性决定了不擦除就无法把某一位从 1 写成 0 之外的状态。要写入新数据,必须先擦除再写入,而擦除的粒度远大于写入。这导致覆盖操作实际上变成了「读出 → 改写 → 擦除目标块 → 写入」的循环,中间状态是旧数据仍然存在的。

第二,磨损均衡会破坏位置对应关系。逻辑块与物理块之间存在映射。当某个物理块即将写满时,控制器会做垃圾回收,把有效数据搬走、擦除旧块。此时「旧内容所在的物理位置」不再对应你当初执行覆盖的那个逻辑块。你覆盖了逻辑块 A,但旧内容的物理副本可能已经被搬到了别的位置。

第三,FTL 日志与映射表本身会留痕。控制器为了支持掉电保护,会把映射关系的变化写入日志结构。这些日志记录里可能包含旧块号、新块号、时间信息,有时还会包含数据的校验信息。日志区的数据不一定被覆盖。

第四,写入过程本身可能失败。如果覆盖写到一半掉电,旧数据可能已经被部分擦除、部分保留,形成的状态既不是原文也不是新文,但仍可能包含可恢复的信息片段。

结论是:覆盖写入只能提高恢复难度,不能消除恢复可能。它适合用来处理「敏感数据不能长期留在介质上」这一合规要求,但不足以对抗有备的提取攻击。

覆盖写入与「安全擦除」经常被当成同一件事,这是最普遍的概念混淆

在很多需求文档里,「数据删除后需要不可恢复」这句话会被直接实现为「删除前先覆写零」。这在合规检查中可能能通过,但在对抗提取攻击的场景里,它挡不住任何具备基本能力的攻击者——因为攻击者不需要攻破覆写逻辑,他只需要在覆写之前就把介质读走一份。

更值得注意的是,覆写本身会显著消耗介质寿命。对大容量数据区做全量覆写,写放大可能达到数十倍,这是一笔实实在在的成本。理解了这一点,就更容易接受「不动数据、只动密钥」的思路。

局限成因实际后果能否靠流程规避
无法原地覆盖闪存擦除粒度大于写入粒度覆盖过程包含读改写中间态不能
旧位置被改变磨损均衡与垃圾回收搬迁数据覆盖逻辑块不等于覆盖物理副本不能
日志残留掉电保护需要记录映射变化日志区可能含旧块号与校验信息不能
写入可能中断掉电、复位、器件异常产生既非原文也非新文的混合态只能降低概率
寿命代价覆写造成额外擦除与写入写放大数十倍,加速介质老化不能

3.3 擦除命令与物理擦除

器件与协议层面通常提供了一类显式的擦除或置无效操作:对闪存介质是擦除单元与块擦除类命令,对块设备是 TRIM / DISCARD 类命令,对安全存储区则有专门的失效或清零流程。它们与「删除文件」的差别在于:它们作用在介质层面,而不是文件系统层面。

这类操作的关键特征是「把块标记为无效,并让器件在合适的时机真正擦除它」。注意这里的措辞——时机由器件决定,不由主机决定。主机能做的只是发出通知,然后由器件在后台完成真正的物理擦除。

这个「延迟」特性带来两个必须理解的后果:

  • 擦除完成之前,数据仍然可读。如果攻击者在擦除窗口内把介质拿走,仍然能读出内容。在长时间不写满的分区里,这个窗口可能很长。
  • 返回成功不等于物理擦除已完成。命令返回成功通常只表示「标记成功」,不表示「物理擦除完成」。把返回值当成擦除完成的凭据,是一个常见误判。

因此,物理擦除的定位应当是:它能防止旧数据在未来被偶然读到,也能减少介质上的信息残留量,但它的时间不可控,无法作为对抗提取攻击的主要手段。真正的保证必须来自「即使数据还在,也读不出来」。

操作层次作用对象时机对提取攻击的作用
文件系统删除目录项与块分配表立即基本无作用
块设备 TRIM / 失效通知逻辑块到物理块的映射立即标记降低作用,取决于回收时机
闪存块擦除物理擦除单元由器件调度中等,受回收时机限制
芯片内部安全擦除受保护区域由器件执行较强,且受认证保护
密码学擦除密钥,而非数据由主机控制,立即生效强,不依赖物理擦除时机

3.4 密码学擦除:密钥即销毁

密码学擦除的思路与前三种完全不同:它不碰数据,只碰密钥。数据以密文形式原样留在介质上,不做任何搬运、不触发额外擦除、不消耗寿命;只要对应的密钥被销毁,那份数据就永久不可读了。

它的强度来自一个非常朴素的性质:在计算能力有限的条件下,没有正确密钥的密文与随机数据不可区分。这不是工程经验,而是密码学的基本假设。攻击者把整颗介质读走、反复分析、用最好的设备去尝试,得到的都只是看起来随机的字节。

这里必须把一个高频误解讲透:密码学擦除的强度来自「密钥被销毁」,而不是「数据被抹掉」。这两句话在工程文档里经常被混用,但它们对应的是完全不同的实现与完全不同的成本:前者改的是密钥存储区的一小块内容,一次写入即可,且不消耗介质寿命;后者要处理整个数据区,写放大巨大且时机不可控。

密码学擦除的前提条件:密钥必须真的被销毁,而不是被标记删除

密码学擦除的全部强度建立在一个前提上——密钥本身不可恢复了。这个前提在实践中经常被破坏:

  • 密钥被「删除」了,但只是改了个文件属性,密钥本体还在介质上;
  • 密钥销毁了,但旧密钥被备份到了别处(快照、镜像、导出文件);
  • 密钥销毁了,但多份相同密钥的副本还有一份活着;
  • 密钥是可从根密钥确定性派生的,而根密钥还在——那么「销毁文件密钥」只是删了一个中间结果,下次派生又会算出来。

最后一条尤其隐蔽:如果文件密钥是从主密钥确定性派生的,那么「销毁文件密钥」必须同时让这次派生不可再现,否则攻击者拿到主密钥就能重算出所有历史文件密钥。第 4 章会用一整节讲这件事。

维度覆盖 / TRIM / 物理擦除密码学擦除
作用对象数据本体密钥
介质寿命消耗显著,取决于数据量极小,一次写入量级
生效时机可能延迟,由器件调度立即,密钥写入即完成
对抗物理提取弱到中等强,密文与随机数据不可区分
能否撤销不能,被擦除即消失在销毁前可以,重建密钥即可恢复
失败模式擦除未真正执行密钥仍有副本可读
适用体量小体量或受监管字段大体量数据的主要手段

3.5 TRIM 与安全擦除的关系与差别

TRIM 是主机与块设备之间的一个通知机制:主机告诉存储设备「这个逻辑块的内容你可以丢弃了」。它的设计目标是提升性能与寿命,而不是提升安全性。

把 TRIM 当成安全擦除,源于一个看起来很自然的推理:「我告诉设备这块数据不要了,设备又真的擦掉了,所以数据没了」。这个推理有三处不成立:

  • 目的是回收,不是抹除。回收的判定标准是「这块数据还有没有有效引用」,而不是「这块数据是否敏感」。对于文件系统层面的删除,块在被回收之前一直处于「有效」状态。
  • 时机不可控。回收发生在器件认为合适的时刻,可能是一段时间之后,也可能因为频繁写入而很快。更麻烦的是,如果后续又有数据被分配到同一块,被回收的旧内容与新内容可能并存于同一物理块。
  • 粒度是块,不是文件。TRIM 通知的最小单位是块。一个文件的数据可能分布在若干块里,也可能与别的文件共用块。块被回收时,回收的是整块内容,与「某个文件已删除」这件事并不严格对应。

所以准确的关系是:TRIM 是回收通知,不是安全擦除;物理擦除是 TRIM 的可能后果,但副作用与时机都不为安全而设计。两者可以配合使用——密码学擦除保证「读不出来」,物理擦除减少「留在介质上的信息量」,但两者绝不能互相替代。

对比项TRIM / 失效通知安全擦除(密码学)
设计目的提升性能与介质寿命保证数据不可恢复
通知粒度块文件或对象
执行方存储设备主机软件
生效时机由设备调度,不确定密钥写入即刻生效
能否撤销不能,回收即丢弃销毁前可撤销
失败模式未及时回收、旧内容与新内容并存密钥存在可恢复副本
在本文中的定位减少残留的辅助手段对抗提取攻击的主要手段

3.6 三种擦除手段的适用边界

把三种手段放在一起,可以得到一个清晰的分工:密码学擦除承担主要的安全责任,物理擦除承担残留控制,TRIM 承担回收效率。三者不是替代关系,而是不同维度上的补充。

在实际产品里,合理的组合通常是:删除文件时销毁文件密钥(立即生效的安全保证)+向存储层发出块失效通知(减少残留)+ 由器件在后台完成物理擦除(长期残留控制)。三步的顺序有讲究:密钥销毁必须在最前面,因为它是唯一一步能立即生效且不依赖器件调度的一步。

需要特别注意的是三类手段都不适用的场景:

  • 运行时内存中的明文。数据在使用期间以明文存在于内存或缓存中,介质层的任何擦除手段都管不到。这一块要靠内存保护、零化、以及尽量缩短明文驻留时间来处理。
  • 快照与备份中的副本。介质被擦除,但快照还在另一个池子里。这是第 4.5 节专门讨论的问题。
  • 被导出的数据。数据曾经通过某个功能导出到别处(诊断日志、崩溃转储、工厂测试镜像),介质上的擦除完全管不到。这属于流程问题,不是技术问题。
数据类型推荐手段理由需要注意
用户业务数据(大体量)密码学擦除为主唯一能做到立即生效且不耗寿命的手段必须配合快照与备份的同步销毁
固件与配置(小体量)物理擦除 + 不可写保护体量小,擦除代价可接受写保护比擦除更重要
日志与诊断数据物理擦除 + 保留期限制需要物理可见性用于排障严格区分可导出字段
临时文件与缓存常规删除即可无敏感信息,重建成本低不要为省事给临时数据也加密
运行时内存明文内存零化 + 缩短驻留介质手段无效崩溃转储路径常被忽略
导出的诊断文件流程管控介质擦除管不到要明确哪些字段允许导出

4. 密码学擦除的工程实现

第 3 章讲清了「为什么要销毁密钥」,这一章讲「怎么把密钥组织起来,才能既安全又可维护」。这一章的每一条都是第 6 章与第 9 章的直接前提。

每文件密钥的层级:删一个文件,只销毁最底层那一把根密钥设备唯一 · 永不出器件不可销毁派生 / 展开主密钥按用途派生 · 常驻受保护区不可单独销毁派生 / 展开文件密钥每文件一把 · 与文件名绑定可销毁 · 擦除的真正对象派生 / 展开数据本体密文 · 留在介质上不动不销毁删除文件时真正发生的事销毁文件密钥 → 同一文件名的任何历史版本同时失效→ 数据本体原样留在介质上,但从此不可读。
图 4 · 每文件密钥的层级与删除文件时的实际销毁点

4.1 每文件密钥的密钥层级

「每文件密钥」这个做法听起来简单,实现起来有一个必须先回答的问题:每把文件密钥从哪里来。如果所有文件密钥都从一个全局密钥直接派生,那么销毁其中一把并不影响派生机制本身,攻击者拿到全局密钥就能重算出所有历史密钥。要避免这一点,就必须建立层级。

一个可用的层级通常有三到四层:

  • 根密钥——设备唯一,出厂时注入,永不销毁,永不离开受保护区。派生树的所有起点。
  • 主密钥——按用途从根密钥派生,比如「用户数据主密钥」「系统配置主密钥」「通信主密钥」。用途分离的意义在于:某个用途的密钥出问题,不会波及其它用途。
  • 文件密钥——从对应的主密钥派生,每文件一把,与文件标识(通常是文件名或其哈希)绑定。这一层是可销毁的、可轮换的、也是擦除动作真正作用的对象。
  • 数据本体——用文件密钥加密后的密文。它从不移动、不被擦除。

这个层级的关键性质是:销毁文件密钥只影响这一个文件,不影响任何其他文件,也不影响派生树的其余部分。这正是「删一个文件就等于删一份数据」得以成立的结构基础。

层级数量关系存放位置可否销毁泄露后果
根密钥每设备一把器件受保护区,永不输出不可销毁全部数据一次性暴露
主密钥每用途一把受保护区或主机安全存储不可单独销毁对应用途的数据全部暴露
文件密钥每文件一把密钥表或文件系统元数据可销毁,擦除的对象仅该文件暴露
数据本体每文件一块普通数据区不销毁无密钥则无信息

4.2 密钥的存放位置与保护

文件密钥本身也是数据,也要被攻击者看到。所以「密钥存哪」这个问题,与「数据存哪」同等重要——而且更容易被忽略,因为密钥通常很小、体量不成问题,容易被随手放在一个「看起来还行」的位置。

存放位置的选择本质上是一个权衡:越安全的位置越难被快速读取,越容易被读取的位置越适合处理大量密钥。常见的可用位置大致有四类:

  • 器件的受保护区域——最强,但容量极小,通常只能放根密钥与少量主密钥。文件密钥放不下这么多。
  • 主机侧的安全存储——比如密钥存储服务、受保护的 NVM 区域。可以放较多密钥,且有访问控制。
  • 密钥表(存放在受保护分区内)——文件密钥集中存放,靠分区权限保护。这是常见的折中,但要注意:密钥表所在分区必须与数据分区同等或更严格的保护级别。
  • 文件系统元数据 / 扩展属性——与文件绑定,紧凑且便于生命周期管理。但元数据区的保护级别通常弱于数据区,这是一个真实风险点。

最常见的错误是把密钥表放在与数据相同的保护级别下。如果攻击者能读数据区,通常也能读到密钥表,那加密就完全白做了。判断标准很简单:密钥表的可读权限必须严格小于等于数据区的可读权限。

一条好用的自查规则:把攻击者能拿到的所有东西列出来,逐一问「这东西能算出密钥吗」

如果攻击者能够拿到介质上除根密钥之外的全部内容(包括所有密钥表、所有密文、所有元数据),那么整个方案的安全性就完全建立在「根密钥不可得」这一条上。这不是缺陷——这正是正确的设计结构。但它要求你确认:根密钥确实拿不到,而不是「理论上应该拿不到」。

具体要确认三件事:根密钥是否在受保护区域内、该区域是否真的不可读、以及受保护区域的状态是否被正确锁定过。第三条经常出问题——设备出厂时保护位没置上,整套机制就从未真正生效过,而软件侧的日志里一切正常。

4.3 密钥派生与轮换

派生解决的是「如何从一把主密钥得到无数把文件密钥」,轮换解决的是「主密钥变了之后怎么办」。这两个机制必须一起设计,否则其中一个一定会出问题。

派生设计的核心要求是三条:确定性(同样的输入必须算出同样的密钥,否则文件就打不开了)、可绑定(派生必须绑定文件标识,否则同一主密钥派生出的一批密钥之间会互相相关,一处泄露波及全部)、以及单向(从派生结果无法反推出主密钥)。第三点通常由成熟的密钥派生函数保证,不需要自己设计。

轮换设计的核心问题是:轮换之后,旧数据怎么办。因为数据是用旧密钥加密的,主密钥一旦轮换,旧密钥就消失了,所有历史数据都会变成不可读的垃圾。可行的做法有三种:

  • _lazy 重加密(也称惰性更新):文件在被访问时顺手用新密钥重新加密。改动最小,但没被访问的旧数据会一直是旧密钥加密的。
  • 批量重加密:一次性把全部数据用新密钥重写。彻底但代价大,且过程中一旦中断就麻烦。
  • 双密钥并存:同时保留新旧两把密钥,新数据用新密钥,旧数据保留密钥索引,访问时按索引选密钥。复杂度最高但最灵活,是第 10 章会详细讨论的方案。
设计项要求不满足会怎样
确定性相同输入必须得到相同密钥文件无法解密,等于数据丢失
可绑定派生输入包含文件唯一标识密钥之间相关,一处泄露波及全部
单向性无法从派生结果反推主密钥拿到任一文件密钥即可反推主密钥
用途隔离不同用途从不同主密钥派生一个用途出问题波及全部用途
算法可替换派生算法可随主密钥版本升级算法有弱点时无法补救

4.4 删除文件即删除密钥

这一节是密码学擦除唯一的兑现动作。前面讲的所有机制,最终都要汇聚到这一件事上:删除文件时,销毁它的文件密钥。

完整动作有四步,顺序不能颠倒:

  1. 确认销毁目标——按文件标识定位到文件密钥的存放位置,确认这是唯一一份副本。注意:如果密钥表里有备份条目、或者文件系统做了快照,这里就漏了。
  2. 标记密钥失效——把密钥条目标记为不可用,让后续任何读取尝试都失败。这一步保证「销毁过程中崩溃」也不会导致旧密钥继续可用。
  3. 物理擦除密钥记录——把密钥记录所在的位置擦除或覆写。这一步是为了减少密钥在介质上的残留量,属于纵深防御,不是主要保证。
  4. 向存储层发出块失效通知——通知介质对应的数据块可以被回收,减少数据本体的残留。

注意这四步里没有一步是在删除数据。数据始终留在原地,保持密文状态。这正是密码学擦除与覆盖写入在成本上的根本差异,也是它能用于大体量数据的前提。

关于「重复文件名」的处理也必须明确:文件密钥如果绑定的是文件名而不是文件唯一标识,那么删除 A 再新建一个同名 A,新文件会继承旧文件的密钥,从而能解开旧文件残留的密文。这是一个真实存在的实现缺陷,设计时必须用唯一标识而不是名字来绑定。

「同名文件继承旧密钥」是一个隐蔽且后果严重的实现缺陷

这个缺陷的成因很自然:实现时图方便,用文件名做绑定键。但它的后果是:攻击者只要保留旧文件的一份密文副本,等同名文件被重新创建后,就能读出旧内容——而此时系统日志里显示「旧文件已删除」,一切看起来都正常。

正确做法是用文件的唯一标识(常见做法是内容无关的唯一 ID,而非路径或名字)作为派生输入的一部分,并保证该标识在删除后不会被复用。这个细节在文件系统层实现时容易被忽略,因为从文件系统的角度看,两个同名文件在不同的时刻确实是「不同的文件」。

步骤动作失败时的后果可重试性
1 定位按唯一标识定位密钥记录找不到即无法确认销毁可重试
2 标记失效标记为不可用崩溃后旧密钥可能仍被读到可重试且幂等
3 物理擦除擦除密钥记录位置密钥在介质上仍有残留可重试
4 块失效通知通知介质回收数据块数据本体残留量偏大可重试

4.5 快照与备份的遗留风险

快照是密码学擦除最常见的漏洞来源。原因很简单:快照记录的是某一时刻的完整数据视图,而密钥表通常也在这份视图里。删除文件后,主数据区的数据被标记为无效,密钥记录被擦除——但如果快照是在这之前拍的,快照里的那份密钥记录仍然完好。

更麻烦的是,快照本身通常没有「让密钥失效」的手段。存储系统不会因为你删除了一个文件,就自动去遍历所有快照并同步删除对应的密钥条目。于是就出现了一个矛盾的状态:业务逻辑上文件已经彻底删除,物理上却存在一份可以直接解密的完整副本。

可行的应对方式有四种,按彻底程度递增:

  • 缩短快照保留期——让快照在删除动作之后很快过期。简单,但受存储系统的最短保留期约束。
  • 删除时同步处理快照——在删除流程里显式触发快照链的清理。彻底,但操作代价高,且不同存储系统的接口差异很大。
  • 把密钥表排除在快照之外——让快照只包含数据本体,密钥单独存放与备份。这是最干净的做法,但要求密钥存储与数据存储分离。
  • 为每个快照周期派生独立密钥——快照与数据用不同的密钥,使得某个快照的密钥被销毁后,该快照内的密文全部失效。代价是密钥管理复杂度大幅上升。
风险来源为什么会残留应对方式彻底程度
存储快照快照保留了删除前的密钥表缩短保留期 / 同步清理 / 排除密钥表取决于实现
数据备份备份含密钥表副本备份加密并独立管理密钥中等
文件系统自身副本日志与元数据可能含密钥启用元数据加密中等
主机内存缓存密钥在内存中有临时副本及时清零 + 缩短驻留较弱
导出与转储诊断数据被导出到外部流程管控 + 字段白名单取决于执行
芯片之外的生产副本产线留存的镜像文件产线密钥管理较弱

4.6 密码学擦除的失效场景

把前面几节的失效模式汇总成一张清单,是为了在设计评审时能逐条对照。这些场景按「隐蔽程度」排列,越往后越难在测试中发现。

最隐蔽的一类是密钥有副本。系统日志显示「密钥已销毁」,测试用例通过,但副本存在于另一个备份池、一份导出文件、或一个测试设备里。这一类问题只有在真正做介质级取证时才暴露。

第二类是机制从未真正启用。比如受保护区域在出厂时状态就是错的,或者派生功能因为某个配置项没开而一直走的是明文分支。这一类的特征是:功能看起来正常,数据也确实加密了,但保护强度是零。

第三类是边界之外:数据被导出、被打印到日志、被包含在崩溃转储里。这一类完全不在介质擦除的能力范围内,只能靠流程与输出管控。

失效场景外部表现内部真实状态发现难度
密钥只是标记删除删除流程正常返回密钥本体仍在介质上高
密钥存在备份副本一切正常备份池里有一份可用密钥高
派生走明文分支数据看起来是密文实际未加密或用固定密钥很高
保护位未正确置位读取受保护区被拒绝区域其实一直可读高
数据被导出到外部介质上数据已删除外部文件里还有完整副本中
崩溃转储泄露介质已清理转储文件里有内存明文中
派生输入绑定错读写都正常同名文件共享密钥很高
清理失败静默忽略流程返回成功部分密钥未被销毁中

这张表的最后一列「发现难度」值得特别强调:最难发现的那几类,共同特点是外部行为完全正常。功能测试通过、回归测试通过、性能达标,但安全强度为零。这解释了为什么安全擦除的有效性不能靠功能测试来保证——它需要专门的介质级验证手段,这部分内容见第 12 章。