搜索全站

输入至少 2 个字符,查找相关内容。

↑↓ 选择 Enter 打开Esc 关闭

EFS 文件系统加密的证书取证

EFS(Encrypting File System,透明加密文件系统)是 Windows Professional 及以上版本提供的文件级加密功能。

最后更新 2026-10-09版本 v2.0维护 DigiForensics查看历史 1

一、概述

EFS(Encrypting File System,透明加密文件系统)是 Windows Professional 及以上版本提供的文件级加密功能。

它工作在文件系统层,加密的是 NTFS 备用数据流 $EFS。文件本身还是那个能被正常读取的 NTFS 文件,只是内容被换成了密文。

这带来一个反直觉但极其有用的特性:

EFS 加密文件的所有者证书如果能在镜像中找到,文件即可被直接解密——不需要口令,不需要暴力破解。

这也是 EFS 和全卷加密最大的取证差异。

全卷加密的密钥受 TPM 与保护器双重保护,而 EFS 的私钥受 DPAPI 保护——而 DPAPI 保护的是"用户凭据",不是文件内容本身。 只要用户的 profile 还在、私钥文件还在,DPAPI 这一层就成了纸糊的。

这个差异决定了两类案件的处置方向截然不同:

场景 全卷加密(BitLocker) EFS
密钥的封装 TPM 密封 / 恢复密码 / 启动密钥 用户证书私钥,在用户 profile 里
取证方向 全盘关键字搜索恢复密码 直接找 RSA 目录下的私钥文件
典型失败原因 用户把恢复密码存到域控、纸质归档或企业集中存储里 用户 profile 被删除、重装系统后私钥丢失
"彻底不可恢复"的含义 罕见——设计上有恢复通道 常见——私钥没了就是数学上不可恢复

EFS 的取证价值恰恰落在那个"常见"上。私钥一丢,文件就真的没了。

所以**"私钥在不在"这个问题必须尽早、明确地回答**,不能拖到"所有方法都试过了"再下结论。

本篇处理的证据形态:

证据 位置 判据 / 说明
$EFS 属性流 NTFS 备用数据流,文件级 文件头带 EFS 特定 header
用户私钥 %APPDATA%\Microsoft\Crypto\RSA\<SID>\,扩展名通常为 .pfx 或无扩展名 最主要的取证目标,DPAPI 保护但明文存在于镜像中
DPAPI master key %APPDATA%\Microsoft\Protect\<SID>\<GUID>\ 用户口令派生密钥保护它,口令已知即可解开
机器级 / 系统级私钥 C:\ProgramData\Microsoft\Crypto\RSA\<SID>\、C:\Windows\System32\Microsoft\Crypto\RSA\<SID>\ 不能与用户级混淆
证书注册表痕迹 HKLM\SOFTWARE\Microsoft\SystemCertificates\Filesystem\Certificates\<指纹>\(用户级在 HKCU) 值 EncryptedFileName 标识 EFS 证书;即使私钥已删,这一条仍可能存在
XP 时代路径 C:\Documents and Settings\<用户>\Application Data\Microsoft\Crypto\RSA\<SID>\ 跨版本取证必须覆盖

注册表痕迹这条要单独强调:它是"该用户曾使用 EFS"这个事实的独立证明。

私钥文件即使被删光,只要注册表条目还在,你依然可以写"该用户曾创建 EFS 证书"。

反过来不行。不能因为私钥不在就写"该用户未使用 EFS"。

EFS 的处置主链是四步,顺序本身就是方法论:

步骤 动作 产出 什么时候就该停
3.1 确认 EFS 使用痕迹 $EFS 流存在性 + 注册表证书条目 两条线索都无 → 写"未发现 EFS 使用痕迹"并列出扫描范围
3.2 提取 EFS 私钥 私钥文件路径 + 所属用户 用户 profile 不在 → 不要假设文件被删,先查未分配空间
3.3 导入证书后解密文件 明文内容 + 实际打开验证 只导入公钥无效 → 不要把"导入了"当成"能解密"
3.4 私钥缺失时的替代路径 内存 / 爆破 / 备份 / 他人证书 全部走完仍无 → 转"不可恢复"的限定表述

第 3.3 步有一个非常常见的失败点值得提前知道:从证书管理器导出的 .pfx 默认包含私钥,而只导出 .cer(不带私钥)时导入成功、文件仍然打不开。

"证书导入成功"与"文件能解密"是两件事,验证必须落到"实际用该证书读出内容"。

在取证流程中的位置:本篇属于分析环节,通常在全卷加密解开之后才轮到它(加密卷里的用户 profile 本身也在加密层之下)。上游依赖是镜像制作与用户 profile 的提取;理解 $EFS 流的存在与读取方式,需要NTFS 数据流与隐藏数据——这篇是本篇的硬前置;HKCU 侧的 hive 提取见注册表取证。

下游支撑是解密后的文件内容分析,通常交给文件头与文件签名判断类型、以及时间线重建纳入时间证据。

DPAPI 机制本身的通用理解见浏览器密码库与 Token 解密——同一套 DPAPI 主密钥解开后,浏览器密码库会同时打开。

该用户是否使用过 EFS、私钥文件是否存在及位于何处、DPAPI 能否解开(有用户口令时)、哪些文件被 EFS 加密、注册表里有哪些证书条目、能否实际解密并读出明文。

私钥不存在且用户口令不可得时,EFS 加密内容在数学上不可恢复——这不是能力问题,是"内容密钥只被那个私钥解得开"的设计后果。

本篇也不能回答**"用户是不是故意加密的"(EFS 是系统特性,默认开启,用户自己往往并不知道)、"这些文件在被加密前的内容是什么"**(密文不保留原文痕迹),以及非 Professional 版本机器上的 EFS 痕迹含义(Home 版无此功能,痕迹值得单独核实)。

读者前提:你需要先掌握 NTFS 备用数据流的读取(NTFS 数据流与隐藏数据)、注册表 hive 的离线提取与查询(注册表取证)、以及 X.509 证书的基本概念(.pfx 何时含私钥、何时只有公钥,这个区分决定了 3.3 步能否成功)。

工作纪律方面,只读挂载与安全接入是前提——证书导入操作会改变取证工作站的证书库,不是原始检材,但必须与检材副本分离。

涉及用户口令的分支见通用密码恢复的授权与最小化要求。

二、核心原理

2.1 双钥体系

EFS 是非对称加密 + 对称加密混合方案。文件用 AES 加密,FEK 又被 RSA 私钥包着:

文件内容  ──AES──→  密文(存入 $EFS 流)
                        ↑
                    FEK(文件加密密钥)
                        ↑
                   用户证书的 RSA 私钥解密
  • 文件加密密钥(FEK):每个文件一把,随机生成,用于 AES 加密文件内容
  • FEK 的存储:被加密后存入 NTFS 的备用数据流 $EFS,用证书的公钥加密
  • 解密过程:用证书的私钥解出 FEK,再用 FEK 解密文件内容

取证意义:只要拿到私钥,所有属于该用户证书加密的文件都能解。

这也解释了 EFS 的经典陷阱——重装系统后文件永久丢失,因为私钥在旧系统的用户配置中。

2.2 私钥存放位置

用户的 EFS 私钥存在 DPAPI 保护下的用户凭据存储里:

位置 说明
%APPDATA%\Microsoft\Crypto\RSA\<SID>\ 用户级私钥(最主要的取证目标)
C:\Documents and Settings\<用户>\Application Data\Microsoft\Crypto\RSA\<SID>\ XP 时代路径
C:\ProgramData\Microsoft\Crypto\RSA\<SID>\ 机器级证书
C:\Windows\System32\Microsoft\Crypto\RSA\<SID>\ 系统证书

关键取证价值:若用户 profile 未被删除,这些私钥文件(扩展名通常为 .pfx 或无扩展名)明文存在于镜像中,只是被 DPAPI 加密。

DPAPI 的保护来自"用户的登录密码派生密钥"——若已知用户密码,DPAPI 即可解开。

2.3 DPAPI 的破解前提

DPAPI(Data Protection API)的解密逻辑:

DPAPI master key(%APPDATA%\Microsoft\Protect\<SID>\<GUID>\)
        ↓ SHA-256
用户密码 + salt
        ↓ PBKDF2 / NTLM
会话密钥
        ↓ 解密 DPAPI master key
master key 明文
        ↓
AES-256-CBC 解密 $EFS 流
FEK 明文
        ↓ AES
文件内容明文

攻击面说白了就三条:

  1. 用户密码已知 → 直接用 mimikatz / dpapi.py / impacket 全部解开
  2. 密码未知 → 离线爆破(DPAPI 支持离线爆破,是真实可行的攻击面)
  3. memory dump 已知 → 从内存中直接读取会话密钥

2.4 证书的注册表痕迹

不管私钥在不在,注册表里通常留有证书元信息:

HKLM\SOFTWARE\Microsoft\SystemCertificates\Filesystem\Certificates\
   <证书指纹>\
      EncryptedFileName   ← EFS 加密的标识值
      FriendlyName
      CertHash

用户级证书则在:

HKCU\SOFTWARE\Microsoft\SystemCertificates\Filesystem\Certificates\

取证价值:EncryptedFileName 是 Windows 内部用于标识 EFS 证书的注册表值。

即使私钥文件已删除,注册表中的证书条目仍可能存在,可用于证明"该用户曾使用 EFS"这一事实。


三、操作步骤

3.1 确认 EFS 使用痕迹

# 1) 搜索 EFS 特有属性流标记
#    EFS 加密文件的 $EFS 流以特定 header 开头
strings -n 20 DigiForensics.dd | grep -i "EncryptedFileName"

# 2) 检查是否存在 EFS 证书注册表项
#    在导出的 hive 中查
grep -aob "Filesystem\\\\Certificates" DigiForensics.dd

X-Ways / FTK Imager 里可以挂自定义关键字:

$EFS                    ; NTFS 备用数据流名
EncryptedFileName       ; 注册表值名

3.2 提取 EFS 私钥(首选)

# 1) 从镜像中提取 RSA 目录(需先切出用户 profile)
#    路径:/Users/<用户名>/AppData/Roaming/Microsoft/Crypto/RSA/<SID>/

# 2) 用已知用户密码解密 DPAPI 保护的私钥
#    工具:impacket 的 dpapi.py
python3 dpapi.py -u domain/user -p password -k rsa.key -c CryptoKeys/*.pfx
# Windows 上用 mimikatz(目标机器或取证工作站)
# 提取当前用户的 DPAPI master key
mimikatz # lsadump::masterkeys /list

# 列出所有 EFS 证书
certutil -store my

3.3 导入证书后解密文件

EFS 取证最实用的就是这一条:

# 1) 导出 EFS 证书(含私钥)为 .cer / .pfx
#    在原系统(或已导入证书的取证机)上:
certmgr.msc    # 个人 → 受信任的根证书颁发机构 / 个人 → 选择证书
               # 右键 → 所有任务 → 导出 → 选择"是"导出私钥 → 后缀 .pfx
# 2) 在取证工作站上导入证书(含私钥)
certutil -user -importpfx "Exported.cer"        # 提示输入密码(导出时设置的)
# 或双击 .pfx → 安装证书 → 当前用户

# 3) 访问 EFS 加密文件
type D:\	est.txt        # 若证书正确,直接显示明文

⚠️ 关键点:导入的证书必须包含私钥。

只导入公钥部分无效——EFS 解密需要私钥解出 FEK。

3.4 无私钥时的替代方案

私钥文件丢了或者被覆盖了,能走的路就这些:

方案 说明
从内存提取 DPAPI 会话密钥 若有内存镜像,DPAPI 会话密钥以明文驻留在 LSASS 进程内存中
DPAPI 离线爆破 DPAPI 支持离线爆破,工具:dpapi.py 的 --brute、hashcat mode 22100
备份恢复 从系统还原点、Windows.old、卷影副本中找回旧私钥
其他设备/用户证书 若文件被多用户共享,其他用户的证书可能也能解密
接受不可恢复 严格意义上,若私钥不存在且密码不可得,EFS 加密内容在数学上不可恢复

四、常见陷阱

4.1 认证与识别误判

误判「EFS 密钥丢失 = 无法取证」

现象:目标机器上找不到当前用户的私钥,报告写"EFS 私钥已丢失,相关文件无法解密"。

原因:EFS 私钥受 DPAPI 保护,而 DPAPI master key 是按用户 SID 分散存放的,系统本身还会复制它。密钥可能躺在别的用户 profile 里、被删账户留下的孤儿 keyfile 里、卷影副本里、系统完整备份里,甚至早就被导出成 .pfx 存到 U 盘或邮件附件上了。

只搜一个 profile 找不到,不等于不存在。

**影