Apple FileVault的技术分析
FileVault 的意思是文件保管箱,是 Apple 公司为 Mac 电脑提供的、基于 MacOS 的加密技术方案,其本质归类于 FDE(Full Disk Encryption,全盘加密)。
注意!与之对应的,为 iPhone 提供的、基于 iOS 的 DataProtect (数据保护)加密技术方案,其本质归类于 FBE(File Based Encryption,文件加密)。
一、Legacy FileVault
2003年,Mac OS X Panther (黑豹,10.3) 首次发布了 FileVault,当时的版本只加密了用户的主目录(不包含启动宗卷),方法是采用一个巨大的稀疏磁盘镜像文件(sparse disk image,区别于普通的磁盘镜像文件.dmg,其实际磁盘占用空间是根据使用情况动态扩展的)作为虚拟磁盘,负责存储加密后的文件数据。在启用 FileVault 功能时,系统会要求用户设置一个主密码,当用户忘记密码时,需要这个主密码或是恢复密钥直接解密文件。
2006年,Mac OS X Leopard(花豹,10.5)做了少许改进,将虚拟磁盘改为稀疏绑定磁盘镜像(sparse bundle disk image,其特点是将文件分割为若干个 8MB 的 Band,在文件修改时无需复制全部内容,仅复制本次修改的 Band,因此备份速度更快,非常适合 Time Machine 的需求)。
Apple 将上述两种版本的技术统称为 Legacy FileVault ,其存在很多严重问题,包括:
- 仅加密用户目录
$home是远远不够的,/tmp和/var/log等目录怎么办? - 主密钥存储在磁盘镜像文件的头部,密钥包裹算法 3DES-EDE 存在破解风险;恢复密钥的包裹算法是 1024-bit RSA,加密强度不高,也存在破解风险
- 文件内容加密采用 AES-128 + CBC 工作模式,但初始向量 IV 没有随机性,设置算法被破解:$IV=trunc_{128}(HMACSHA1(hmac-key||trunkno))$
- MacOS 置于睡眠模式时,内存数据直接写入磁盘文件
/var/vm/sleepimage,缺乏加密保护存在密钥泄露风险
这些问题的根源,还是由于底层文件系统 HFS+ 不支持 FDE 加密,只能基于“应用软件模拟 + 专用磁盘镜像”的替代方式实现,导致功能受限而且效率低下。
二、基于 CoreStorage 的 FileVault 2
2010年,Mac OS X Lion (狮子,10.7) 发布了 FileVault 2,基于 CoreStorage 虚拟化技术推出一个重新设计的 FDE 方案,主要改造点包括:
- 随着 NIST 技术标准的演进,将 AES-CBC 替换为 AES-XTS 磁盘加密模式,分组长度为128位,密钥长度为256位,并支持基于 AES 指令集的硬件解密(如Intel Broadwell 架构的CPU,加密模式只有3%的性能损耗)。
- 在磁盘和文件系统之间增加了一个虚拟化层,也就是命名为 CoreStorage 的 LVM (Logic Volume Manager,逻辑卷管理器),类似于 Veritas Volume Manager 和 OSF LVM,但底层文件系统仍然是 HFS+。
- 支持将User Password作为加密因子,而且支持 MacOS 的每个用户使用各自的用户密码来计算用户密钥,并解锁加密数据,非常有利于用户隐私保护!
1. 启用方式
当用户启用 FileVault 时,主要任务包括:
- 系统自动生成并要求用户保存
Recovery password

- 自动将已有数据卷转换为 CoreStorage 加密卷,并将分区封装为 PV,将其导入 LVG,并设置 LVF 和 LV 以包含新的文件系统。
- 新建一个 Recovery HD 分区卷,并将 CoreStorage 加密卷设置为启动分区。
1 | Mikes-MacBook-Pro-3:~ mikej$ diskutil list |
2. 技术实现
通过diskutil corestorage list命令,可以查看 CoreStorage 的层级结构为:
Physical Volume -> Logical Volume Group -> Logical Volume Family -> Logical Volume
1 | CoreStorage logical volume groups (1 found) |
LVF- logical volume family 是 Apple 自定义的层级,用于 LV 逻辑卷特定属性的继承。
系统变量com.apple.corestorage.lv.familyUUID用于构造 AES-XTS 的 Tweak key 的加密因子。
三、基于 APFS 的 FileVault
2017年,MacOS High Sierra(内华达脊岭,10.13) 正式启用了 APFS(Apple FileSystem),用于替代古老的 HFS+。
作为新一代的文件系统,APFS 专门针对闪存/SSD进行优化(但依然可用于传统机械硬盘),提供了更强大的加密、写入时复制元数据、空间分享、文件和目录克隆、快照、目录大小快速调整、原子级安全存储基元,以及改进的文件系统底层技术,将全面应用于该公司旗下 MacOS、iOS、iPadOS、tvOS、watchOS等所有设备中。其突出特点包括:
- inode编码长度提高到64位,单一Volume的文件数量大大增加;时间戳精度提高到纳秒,有助于实现原子性和原子事务;目录大小是单独存储的,无需每次实时计算目录容量;文件和文件夹名称被规范化,完全支持Unicode
- 支持COW(Copy On Write,写入时复制):几乎立即复制文件或目录,元数据多次存在于文件结构中,但共享相同的数据存储空间;修改克隆时,文件系统仅记录数据更改
- 支持快照(Snapshot):支持创建特点时间点、文件系统只读实例的快照
- 支持空间共享:使用 GPT 分区方案,单一容器内部包含多个 Volume 共享物理存储容量,并可以相互访问,但不与其他容器共享数据

关于加密功能,APFS 引入 container(容器)并整合了 CoreStorage 技术,完全实现了文件系统层级的原生实现,包括:
- 支持对容器、卷和文件使用的数据结构进行加密。当一个volume是加密的,它的文件系统树和该卷中的文件内容都是加密的
- 统一实现了 FDE 和 FBE,支持三种加密模型:不加密、单密钥加密、多密钥加密,但MacOS 目前似乎仅支持 FDE 模式
- 支持硬件加密和软件加密。
硬件加密适用于Apple提供的内置存储(例如带有T2安全芯片的 MacOS 和 iOS 设备);
软件加密适用于用于外部存储,以及不支持硬件加密的设备上的内部存储;
使用硬件加密时,只有操作系统内核可以与内部存储交互;
根据硬件的不同,可以使用 AES-XTS 或 AES-CBC 加密模式。
层级结构也调整为:Physical Store -> Contianer -> (Volume Group) -> Volume
1. 技术分析(Intel CPU)
示例是一台 Intel CPU 的 iMac 设备,因此并没有安全隔区等 Apple 专用 Soc 设备。
命令行df -h查看文件系统
1 | sj@JiandeiMac ~ % df -h |
通过diskutil list,可以看到物理硬盘disk0包含了2个分区,分别是EFI启动分区disk0-s1和APFS分区disk0-s2,并将后者同步映射到disk1。
1 | j@JiandeiMac ~ % diskutil list |

用于启动 Mac 的 APFS 容器必须包含至少五个宗卷,其中前三个宗卷对用户隐藏 :
- Preboot Volume:包含启动容器中每个系统宗卷所需的数据
- VM Volume:MacOS 用于交换文件储存
- Recovery Volume:包含 recoveryOS,进入Recovery模式可以清除用户密码
- System Volume:包含用于启动 Mac 的所有必要文件、macOS 原生安装的所有 App
- Data Volume:包含用户文件夹中的任何数据、用户安装的 App、第三方 App、用户拥有且能够写入的其他位置
每增加一个系统宗卷, 便会创建一个数据宗卷。3个隐藏宗卷全为共享宗卷且无法复制。
通过diskutil apfs list,可以查看容器 disk1 的详细信息。
1 | sj@JiandeiMac ~ % diskutil apfs list |
通过diskutil apfs listusers $Volume_ID,查看当前有效的用户密钥信息,即有几个 KEK 副本。
1 | sj@JiandeiMac /Volumes % diskutil apfs listusers 925F8706-12D2-305B-B8E0-14201AF1D027 |
2. 签名系统卷(M1 CPU)
MacOS 10.15 Catalina 引入了 APFS Volume Group,系统卷和数据卷属于同一卷组,并且在 Finder 中被视为一个卷;引入了只读系统宗卷,这是一个专用于系统内容(通常名为“Macintosh HD”)的独立宗卷,默认不能写入数据,甚至 Apple 系统进程也不能。
MacOS 11 Big Sur 将只读系统宗卷升级为签名系统卷 (SSV,Sealed & Signed System Volume),进一步增加了操作系统的签名保护,甚至现在启动系统的都不是真实的 System 卷宗,而是启动时创建的一个快照。
SSV 具有的内核机制会在运行时验证系统内容的完整性,并拒绝不含来自 Apple 的有效加密签名的任何代码和非代码数据。此外,还有一个附带的优势,在进行操作系统更新时如果发生意外无法执行, 无需重新安装即可恢复到旧系统版本。
SSV 签名系统卷依赖于 SKP 密钥(Sealed Key Prtection,密封密钥保护,也称为操作系统绑定密钥),也就是依赖于 Apple 安全隔区硬件,因此 Intel CPU 不适用。
通过 diskutil list,可以看到物理硬盘disk0包含了3个容器:
- Apple_APFS_ISC 容器:ISC(iBoot System Container)容器负责在早期引导过程中支持 iBoot 固件,并为 M1 SoC 中的 Secure Enclave 提供可信存储。
iSCPreboot 卷是指定的引导程序,空的 Recovery 卷用于恢复。xART 卷提供可信存储,Hardware 卷包含与硬件相关的文件。 - Apple_APFS_Recovery 容器:专用于提供 1TR,存储在其 Recovery 卷上。包括 iBoot 的第二部分以及 M1 的完整恢复模式所需的所有内容。
该 Recovery 卷被指定用于恢复,但此该容器没有单独的引导程序卷。 - Apple_APFS 容器:M1 的引导容器 Apple_APFS 也与 Intel Mac 上的引导容器不太一样:一个细微但显著的区别是数据卷不是命名为“Macintosh HD - Data”,而是简单的“Data”。如果使用依赖于按名称查找数据卷的代码,则要重新检查它代码是否仍然有效。
尽管此容器仍有一个 Recovery 卷,但该 Recovery 卷已经受到了一些限制,比如无法访问安全策略等,在引导到恢复模式时也没有使用该 Recovery 卷。
1 | sj@SunJiandeMacBook-Air ~ % diskutil list |

通过diskutil apfs list,可以发现增加了一个签名系统卷disk3-s3,隐藏了一个系统卷disks3-s2,实际指向了 SSV 的快照disks3-s3-s1。
1 | sj@SunJiandeMacBook-Air ~ % diskutil apfs list |
四、FileVault的密钥层级
对比 Data Protection 数据保护技术,FileVault 等价于 C 类,使用基于 AES-XTS 的 FDE 全盘加密模式保护卷宗数据。经过多年的技术演进,最新、最复杂的 Apple FileVault 密钥层级如下图。

- SKP(Sealed Key Prtection,密封密钥保护,也称为操作系统绑定密钥):Apple 为其设计的 SoC 设备开发的,旨在确保其专用设备被拆解、或使用未认证的操作系统版本等场景下,无法获取加密材料,目的是为系统密钥提供独立于安全隔区的额外保护。
注意!SKP 功能不是由安全隔区提供的,而是由位于更底层的硬件寄存器支持,实际上是基于安全隔区操作系统 sepOS 加载时的测量值。这也意味着,其仅在搭载 Apple 设计的 SoC 的设备上提供。 - xART(eXtended Anti-Replay Technology,扩展反重放技术):一组为具有反重放功能 (基于物理储存架构) 的安全隔区提供加密且经认证的永久储存区的服务。
xART 是 Apple 设计的第二代安全存储组件,增加了一个计数器加密箱,包括:1个128位盐,1个128位密码验证器,1个8位计数器,1个8位最大尝试值。 - KEK(Key Encryption Key,密钥保护密钥):派生密钥,基于用户口令、SKP密钥和硬件密钥(基于UID派生)进行密钥扩展生成
- VEK(Volume Encryption key,卷宗保护密钥):随机生成密钥,基于 KEK 和 硬件密钥进行包裹,并被 xART 保护,就是用于卷宗数据加密的 AES-XTS 的分组密钥 key1。
如上所述,搭载 Apple 芯片的 Mac 以及搭载 T2 芯片的 Mac 通过构建和管理密钥层级实施内部宗卷加密,基于芯片内建的硬件加密技术而构建。
在搭载 Apple 芯片的 Mac 以及搭载 T2 芯片的 Mac 上,所有文件保险箱密钥的处理都发生在安全隔区中;加密密钥绝不会直接透露给 Intel CPU。
所有 APFS 宗卷默认使用宗卷加密密钥创建。宗卷和元数据内容使用此宗卷加密密钥加密,此宗卷加密密钥使用类密钥封装。 文件保险箱启用时,类密钥受用户密码和硬件 UID 共同保护。
如果没有有效的登录凭证(User passcode)或加密恢复密钥(Recovery key),即使物理储存设备被移除并连接到其他电脑,内置 APFS 宗卷仍无法解密,以防止未经授权的访问。
删除宗卷时,其宗卷加密密钥由安全隔区安全删除,这有助于防止以后使用此密钥进行访问 (即使是通过安全隔区)。另外,所有宗卷加密密钥都使用媒介密钥封装。媒介密钥不提供额外的数据机密性,而是旨在启用快速安全的数据删除,如果缺少了它,则不可能进行解密。
在搭载 Apple 芯片的 Mac 和搭载 T2 芯片的 Mac 上,媒介密钥一定是由受安全隔区支持的技术来抹掉,例如远程 MDM(Mobile Device Management,远程-移动设备管理) 命令。以这种方式抹掉媒介密钥将导致宗卷因存在加密而不可访问。
可移除储存设备的加密不使用安全隔区的安全性功能,而是采用与基于 Intel 的 Mac (不搭载 T2 芯片) 相同的方式执行加密。
1. 版本演进
- 在 macOS 10.7 Lion 中,引入了 CoreStorage 管理卷,并规定 VEK 密钥的创建点是用户在 Mac 上启用FileVault的过程中。
- 在 macOS 10.13 High Sierra 中,引入了 AFPS 文件系统,VEK 密钥的创建点调整为:用户创建过程中、 设定首位用户的密码或 Mac 用户首次登录过程中。换句话说,无论用户是否启用 FileVault,卷宗数据都会被加密,其区别仅在于:
- 如果没有启用 FileVault 功能,宗卷加密密钥仅由安全隔区中的硬件 UID 保护

- 如果稍后启用了文件保险箱 (由于数据已加密,该过程可快速完成),反重放机制会帮助阻止旧密钥 (仅基于硬件 UID) 被用于解密宗卷,然后宗卷将受用户密码和硬件 UID 共同保护
- 如果没有启用 FileVault 功能,宗卷加密密钥仅由安全隔区中的硬件 UID 保护
- 在 macOS 10.15 Catalina中,这是第一个仅支持 64 位应用程序的 macOS 版本!引入了 Bootstrap Token 功能,也就是为密钥层级增加了 SKP 保护层,并为后续签名系统卷宗 SSV 提供了技术基础。
- 在 macOS 11 Big Sur 中,系统宗卷通过签名系统宗卷 SSV 功能进行保护(实际上仅提供操作系统的快照),而数据宗卷仍通过加密进行保护。
2. KEK的多副本
Apple公司定义了几种获得 KEK 的方式:
- 用户口令(User password):系统登录时用户输入口令。为保证必要的安全强度,系统实际使用的密钥必须经过密钥拉伸
- 个人恢复密钥(Personal recovery key):在格式化驱动器时生成的,并由用户保存在纸上或打印输出,系统或厂商并不留存
- 机构恢复密钥(Institutional recovery key):允许相应的公司获得 KEK,需要用户设置后生效,或者厂商偷偷强制设置!
- 远程恢复密钥(iCloud recovery key):用户在Apple公司的远程支持下进行系统恢复
为支持不同的场景,keyBag 将同时存储多个 KEK 的副本,例如用户口令采用密钥包裹方式存储,而 iCloud 恢复密钥采用非对称的公钥加密存储,不同场景使用不同的包裹密钥,这也体现了多层级密钥管理的价值所在。
五、FileValut 2 的解密代码实例
根据Infiltrate the Vault: Security Analysis and Decryption of Lion Full Disk Encryption - Omar Choudary,密钥层次如下图。
参考FVDE工具包,可以查看实现代码。

1. CoreStorage Header
在 CoreStorage 加密卷的 Header,存储了核心的加密信息,包括:卷头部签名、块大小、卷大小、元数据大小、第一个元数据块块号、第二个元数据块块号、第三个元数据块块号、第四个元数据块块号、加密方法、Physical Volume UUID(用于解密加密的密钥文件)、Logiccal Volume Group UUID 等。
2. EncryptedRoot.plist
在恢复数据卷 Recovery HD,有一个加密文件包含了提取 VMK 所需的全部信息,路径是:com.apple.boot.X/System/Library/Caches/com.apple.corestorage/EncryptedRoot.plist.wipekey
这个文件本身也是基于 AES-XTS 加密的,分组密钥就是 CoreStorage 头部存储的AES-XTS key1,可调整密钥是 128 位的全零,解密成功后的内容实例:
1 |
|
3. Volume Master Key
解密后的 plist 文件是一个 XML 文件,其中的关键字段如下,注意实际存储格式是 base64 编码:
PassphraseWrappedKEKStruct
KEK(Key Encryption Key,密钥保护密钥)的构造体:AES包裹的KEK,PBKDF2算法的盐。
包含了 2 个 284 位 的数据块,分别用于 recovery password 和 user password。

注意!MacOS 的每个用户都有其自己关联的 PassphraseWrappedKEKStruct
APFS 称之为 VEK(Volume Encryption Key)
KEKWrappedVolumeKeyStruct
VMK(Volume Master Key,卷宗主密钥)的构造体。
数组有多个成员,其中标记为AES-XTS的就是 KEK 包裹的 VMK。
KeyWrappedKEK
如果用户开启了 icloud 远程备份,plist 文件将包含该字段,其数据块结构如下:
注意!icloud 恢复是另一个基于非对称密钥算法 RSA 封装的 KEK
伪代码实例
无论基于 recovery password,还是 user password,都需要通过 PBKDF2 算法进行密钥拉伸。
注意!recovery password 是字符串格式,包括数字之间的破折号。

1 | p = get_user_password() |
4. Volume Tweak Key
用户数据 AES-XTS 加密模式的 tweak key 也是128位,构造方式是:$trunc_{128}(SHA256(VolumeMasterKey || LogicVolumeFamilyIdentifier))$
上个流程已经找到 VMK,那么如何找到 LV Family UUID 呢?
- 在 CoreStorage Header 中,第104字节提供了字节偏移量,就是 Disk Label Metadata 的存储位置
- 在 Disk Label 中,第220字节提供了字节偏移量,就是 Encrypted Metadata 的存储位置
即:$offset = DiskLabel[DiskLabel[220] +32]$ - Encrypted Metadata 基于 AES-XTS 加密,分组密钥也是 CoreStorage Header 的 AES-XTS Key1,可调整密钥是 CoreStorage Header 的 PV UUID
- 解密后的 Encrypted Metadata,第280字节提供了字节偏移量,就是 XML Metadata 的存储位置

- 有3个 XML 文件,包含了许多UUID,其中第1和第3个 XML 文件包含了 Logical Volume Family UUID,就是下图中蓝色字段

参考文献
- Legacy FileVault 漏洞报告
- MacOS X 的 Corestorage 逻辑卷组管理器 - Stephen Foskett
- MacOS 的安全和隐私指南
- Working with APFS Volume Groups
- APFS 科普贴
- APFS Structure
- M1 Macs radically change boot and recovery
- Mac 迁移指南:换新机后的任务清单
- FileVault Drive Encryption 代码库 - Github