讨论文件透明加密,容易陷入算法选型的表层比较。实际上,AES、SM4、SM2、SM3 都有成熟实现,密码库调用并不构成主要工作量。真正决定系统能否稳定落地的,是文件系统过滤层的位置选择、元数据与文件语义的兼容、密钥封装的断电恢复,以及离线授权的时效控制。下面按工程实现顺序拆解。
应用层 Hook ReadFile/WriteFile 看似简单,但会漏掉内存映射、直接 I/O、备份接口等路径。Minifilter 注册 pre/post 回调,拦截的是 IRP,覆盖面更完整,但代价是上下文判定更复杂。
第一个问题是路径取得时机。pre-create 阶段拿到的相对路径可能是短名或未规范化形式,直接用于策略匹配并不可靠。更稳妥的方式是在 post-create 阶段获取规范化最终路径,并区分“打开路径”和“最终路径”。硬链接、符号链接、重命名都会造成二者不一致;若策略按路径授权,判定应落在最终路径上,否则可通过链接绕过。
第二个问题是进程身份。FltGetRequestorProcessId 返回的 PID 可能被复用,不能单独作为授信依据。常见做法是取进程映像哈希或签名,并在驱动侧缓存结果,避免每次 I/O 都重新校验。缓存失效策略需要与进程退出、映像替换事件联动,否则会留下陈旧授权。
第三个问题更隐蔽:paging I/O 的发起者不是应用进程。应用建立文件映射后,缺页读由内存管理器发起,此时按 PID 判定会直接失效。可行的替代信号是文件对象的 stream handle context:在 create 阶段完成授权判定并挂接上下文,后续 paging 读复用同一文件对象上的判定结果,而不是重新取请求进程。
post-write 回调里缓冲区数据已经被 Cache Manager 接收,此时原地加密缓冲区,并不能保证后续 paging write 写出的就是密文。明文仍可能落盘。可选路径有两条:在 pre-write 返回 FLT_PREOP_COMPLETE,自行构造同步加密写;或者接受额外 I/O 放大,走完整拦截。前者要处理自发起 I/O 重入,后者要评估吞吐损失。两者都是真实取舍,没有免费方案。
磁盘上的加密文件通常不是纯密文,而是“头部元数据 + 密文正文”。头部承载算法标识、密钥版本、被 KEK 封装的 DEK、nonce 和策略标识。把元数据放头部而非尾部,是为了避免追加写时反复移动元数据。
但头部改变了物理文件长度,应用层期望的却是明文长度。因此 EndOfFile、AllocationSize 以及目录枚举返回的大小都要做负向补偿;截断操作则要反向加回头部偏移。任何一条漏掉,表现就是“文件能打开但大小异常”或“截断后内容损坏”。
加密模式也受业务负载约束。GCM 需要从流首累积 GHASH,不适合大文件中段随机读写;需要随机访问时,XTS 或“CTR 加分块独立校验”更常见。把模式写成容器版本字段,而不是硬编码在代码里,是后续升级的前提。
文件级 DEK 的价值在于隔离:单文件泄露不波及同目录其他文件。但 DEK 必须被封装,否则头部等于明文密钥。国密体系下常见构造是 SM4 加密正文、SM2 或 KEK 封装 DEK、SM3 做完整性校验。
封装算法本身也有细节。AES-KW 比直接用 CBC 加密 DEK 更合适,因为前者带完整性校验,能发现封装块被篡改。更关键的是 KEK 轮换时的原子性:旧 KEK 解出 DEK,新 KEK 重新封装,写回头部,正文不动。若写一半断电,文件头损坏会导致文件永久不可解。可行方案是头部采用 A/B 双槽,各带版本号和 CRC;写入时先写非活动槽并刷盘,再翻转指针并再次刷盘。代价是每次头部更新至少两次刷盘,收益是把“断电毁文件”降为“回退到上一版本头”。
设备离开企业网络后,解密不能依赖在线查询,通常以带时效的票据缓存解封材料。票据本质上是短时效 KEK 封装,有效期由签名时间戳和客户端单调时钟共同约束。时钟回拨是现实攻击面,纯软件侧无法完全防御,需要单调计数器或 TPM 提供可信时间源。这也决定了离线窗口不能设得过长。
需要明确的是,上述机制覆盖的是“文件作为字节流经文件系统 I/O 离开授权环境”。截屏、剪贴板粘贴到非受控进程、进程将解密内容另存为新文件,都不经过过滤驱动的判定路径。这不是实现缺陷,而是拦截点位置决定的能力半径。审计事件也必须在驱动内部产生:哪个进程、命中哪条策略、使用哪个 DEK 版本,只有过滤回调掌握这些上下文。
迪康在这条实现路径上的取舍基本落在上述约束内:Minifilter 拦截、版本化容器头、DEK/KEK 两级封装与版本路由。评价一套驱动层透明加密是否成熟,值得追问的不是“支持哪些算法”,而是它在 paging I/O 授权、缓存一致性、截断偏移换算、头部双槽写入和离线票据防回拨这些硬点上,是否给出了可被工程验证的回答。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。