既然解开bitlocker需要密钥,那Windows正常启动(无用户输入)时是从哪里获取到密钥的?
更新于:2025-03-24 11:42:56

磁盘全盘加密技术,如果只说用TPM的话,我个人感觉还是不能说明问题的。网上关于TPM的介绍大多数都是重复的那几句话,并没有介绍TPM到底以什么样的方式工作的。

比如用户是可以改密码的,但是改密码并没有影响bitlocker的运行,改密码是瞬间完成的,说明改密码不影响加密结果。

绝大多数全盘加密的软件实现里(包括并不限于:bitlocker,trueCrypt,安卓的全盘加密等等),需要解决的两个最重要的问题是:

1. 加密解密性能要足够快

2. 用户可以随意改密码,这个改密码的过程必须立即生效,而不是重新解密、加密所有数据。

注:本文中提到的盘,一般指的是分区,而非物理的整个盘,虽然很多软件也支持物理全盘加密,但通常情况下,加密都是针对分区层面的。

对于第一条,也就是性能问题,绝大多数加密算法,都使用对称加密算法(比如AES-128/256),因为非对称算法的计算量太大,不能满足日常需求。磁盘加密算法,一般情况下使用的是AES-XTS或者它的变种,AES算法有ECB、CBC、XTS等若干变种:

ECB:把数据拆分成若干组,每一组独立加密、解密,这种算法有一个缺陷,就是当有黑客获取了足够多的样本以后,是有可能暴力破解的,因为只要是同样的数据内容,ECB加密的结果一定是相同的。

CBC:把数据拆分成若干组,使用一个初始化向量(IV),前面每一组的数据加密完以后,都会产生一个新的值,简单的说就是把前面一组的数据的加密结果,作为后面一组数据加密的一部分输入,这样的好处就是即使黑客截取了足够多的样本数据,破解起来难度仍然很大,因为即使是同样的内容,在数据流的位置不同,加密后的结果也不同。网络传输加密经常使用这种算法。

XTS:因为CBC算法里,后面的数据解密的时候,需要依赖前面的解密结果,这就意味着要解密第N块数据,就需要解密前面1到N-1块的数据,但是磁盘数据都是一块一块独立的,不可能一次性把整个磁盘上GB/TB的数据都解开(性能也不允许),所以XTS是加入了一个Tweak key的概念,Tweak key可以是扇区号(或者类似的概念),这样就可以相对独立的加密每一个扇区块,又保证即使扇区内容相同,加密后的内容也不同(因为扇区号不同,Tweak key不同)。

解决了性能的问题,剩下的就是要解决用户改密码的问题。如果直接使用用户的密码加密,那么如果用户改密码,就需要全盘数据全部解密、再加密,对于整盘数据来说,这样的效率是不允许的。所以针对全盘数据加密解密,通常使用二级(或者多级)密码实现的。

当要启动整盘加密时,生成一个随机的,超长的秘钥,有些地方叫做master key,这个master key是用来直接给数据加密解密的(用于AES-128/256)。但是这个秘钥太长了(128/256位二进制数),而且也不能更改(更改了就要全盘解密),用户提供的密码,是用于加密这个master key的,这个过程使用的一般是非对称加密技术(比如RSA等),相当于用户输入密码以后,通过非对称加密算法,解开真正的master key,然后再用master key解密真正的数据。不管用户怎么修改密码,这个master key是不改变的

TPM这类安全外设,就是保存这个master key的。master key不在盘上,而在外设里。

讲到这里,细心的人会发现:master key既然是存在TPM外设里,那么就可能有这些问题:

1. 既然master key在TPM里,TPM怎么保证不被第三方工具读取,为什么TPM只认Windows?

2. master key从TPM传输给操作系统时是否会被截取?

3. master key在内存中是否能被其他恶意软件截获?

一条一条解释:

1. 既然master key在TPM里,TPM怎么保证不被第三方工具读取,为什么TPM只认Windows?

显然如果TPM是一个U盘之类的可以被任何人访问的东西,那么它必然是存在被破解的可能的。TPM之所以叫Trusted Platform Module,是因为它在存储秘钥的过程中,使用了一系列的安全手段,比如要校验操作系统的证书

所以Linux上想要直接使用TPM作为安全认证很麻烦,因为大多数TPM只信任“安全”的证书,对于Linux来说,自己编译的内核是没办法签发让TPM信任的证书的。TPM只信任它认为“安全”的操作系统,这个操作系统只有Windows这类二进制发布的,带有证书校验的操作系统。自己随便编译的Linux内核是无法读取TPM的内容的。

2. master key从TPM传输给操作系统时是否会被截取?

前面提到了TPM的通信过程中要做证书校验,这个过程使用了非对称加密算法,TPM返回给操作系统的master key是经过加密的,这个过程跟HTTPS/SSL的通信过程类似,建立通信之前,双方要校验证书(把Windows当成HTTPS服务器,TPM是浏览器客户端),之后双方通信的内容会使用证书加密。这样即使有人能把TPM的物理信号截取出来,也无法直接获取master key的内容(它是加密过的),解开master key的秘钥只有Windows自己才有。

3. master key在内存中是否能被其他恶意软件截获?

这种风险是存在的,因为操作系统要解密,必然是要把master key保存到内存的某个地方,然后调用AES算法进行解密的。早期的bitlocker版本里,确实有攻击者可以通过某些手段攻击到内核中,然后在特定的内存位置找到AES的秘钥

对于这种攻击手段,微软在Windows 10里提供了内核DMA保护的技术来阻止这种攻击。

当然,现在还有其它攻击方案,比如“冷启动攻击”:计算机在关机以后,内存中的内容并不会立即消失,通常会有几秒甚至几分钟的延迟,如果黑客可以在Windows关机以后获得硬件控制权,然后直接把内存中的数据全部复制出来,还是能找到master key的。应对冷启动攻击的办法也有很多,比如在操作系统关机之前,把所有master key的内存全部写0x55/aa几次。但是由于内存中的数据很多,操作系统要百分百保证数据安全还是有困难的。

微软的bitlocker有没有别的安全漏洞?

我能想到的,有很多,比如:

1. master key在服务器的安全性问题:

磁盘加密的master key,其实就是微软服务器上保存的那个恢复秘钥ID,微软为了防止用户忘记密码,在启动bitlocker的时候,会把master key保存一份。所以如果自己的微软账户泄漏了,那么别人也是有办法通过微软账户来获取master key。

所以有很多大公司,并不使用微软的服务器来保存master key,而是自建一个域服务器来存储。这样哪怕微软那边出了什么问题(比如,被美国政府控制),那么微软也无法拿到master key。

2. AES-XTS自身的安全问题:

因为AES是分组加密,数据是被分成一块一块的,那么如果原始数据内容相同,加密后的数据也是相同的,为了避免这种安全问题,磁盘加密使用的是XTS,也就是使用一个类似块编号的方法,把块编号本身作为加密的一部分输入。

但这里还有一个问题:XTS的Tweak key是通常是扇区地址,而一个扇区的大小远远大于AES的加密数据单元(一组数据是16/32字节),那么就意味一个扇区内的所有数据使用的tweak key是相同的,那么如果扇区内有重复的数据,AES-XTS也会生成重复的内容。对于目前4K的大扇区来说,这种安全隐患不容忽视。

微软曾经在早期的bitlocker中使用了扩散器的机制(elephant diffuser),让扇区内的所有数据产生关联性,也就是说,如果扇区内的第一组AES数据发生了改变,那么这个改变会影响整个扇区内所有组AES数据的加密结果。但是这个机制因为性能问题被移除了,所以这是一个AES-XTS的安全漏洞,如果AES分组大小不变的情况下,大扇区的存储介质,安全隐患会更大一些。虽然AES-XTS算法本身已经足够安全了,但是道高一尺魔高一丈,任何安全漏洞都不应该忽视。