
您如何能确定,从电脑开机的那一刻起,其上运行的软件就是真实可信的,并且没有被隐蔽的底层恶意软件所侵害?这个关于数字信任的根本性问题,是现代计算机安全的核心。传统的杀毒软件是不够的,因为一个老练的攻击者可以在操作系统加载之前就将其攻破。解决方案是一个强大的、以硬件为锚点的程序,即安全启动过程,它从芯片层面开始构建一条可验证的完整性链。
本文将对这项基础安全技术进行全面探讨。首先,在“原理和机制”一章中,我们将剖析使安全启动成为可能的核心密码学概念,从不可变的信任根到验证每一步的数字签名链。我们将区分安全启动和度量启动,并探讨系统如何防御巧妙的攻击。接着,在“应用与跨学科联系”一章中,我们将了解这些原理在现实世界中如何应用于保护从个人笔记本电脑、汽车到庞大的云计算基础设施的方方面面,从而在一个零信任的世界中建立信任基础。
您如何能确定,您刚刚打开的计算机真正是您的计算机?不仅仅是物理的盒子,还有机器的灵魂——内部运行的软件。您如何知道没有某些微小的恶魔已经钻入其核心,从电源灯亮起的那一刻起就等着监视您的一举一动?这不是偏执的幻想,而是计算机安全领域最深刻的挑战之一。答案是一个以非凡的优雅和逻辑著称的过程,即安全启动。这是一段信任之旅,信任的链条一环扣一环地锻造而成,始于一块因其本质而不可改变的硅片。
想象一下,您收到一份皇家法令。您相信它来自国王,因为它盖有他独特而复杂的蜡封。但这只有在您已经知道国王真正的印章是什么样子,并且您绝对信任这一知识的情况下才行得通。在计算世界中,我们需要一个类似的、无可指摘的起点。我们需要一个信任根。
这个根不能是硬盘上可以被修改的普通软件。它必须是某种基础且不可变的东西。在现代芯片上,这个角色由一小段直接蚀刻在只读存储器 (ROM) 硅片上的代码扮演。这段引导 ROM 代码在制造过程中被“烘焙”进去。任何软件,无论是恶意的还是其他的,都无法擦除或覆盖它。它是计算机最原始的真理,是处理器从冷启动中唤醒时将执行的第一条可信指令。这个不可变的模块就是我们的数字“国王印章”,是后续一切的锚点。
启动计算机不是单一事件,而是一个序列。简单的引导 ROM 加载更复杂的固件(如今天常见的 UEFI 系统),固件再找到并加载操作系统 (OS) 内核。这是一场软件组件的接力赛。但我们如何确保没有人将合法的选手换成恶意的冒名顶替者呢?
答案是一条简单而强大的规则:先验证,后执行。在任何新的软件片段被赋予机器控制权之前,当前运行的可信软件必须首先为其完整性和真实性作担保。这就创建了一条信任链。
要执行此检查,我们需要两个密码学工具:
加密哈希(数字指纹): 一个加密哈希函数,我们称之为 ,是一种数学算法,它接收任意大小的文件,并计算出一个小的、固定大小的字符串,即其“哈希”或“摘要”。这个哈希就像一个独特的指纹。如果您更改原始文件中的哪怕一个比特——将一个 0 翻转为 1——产生的哈希也会以不可预测的方式完全改变。因此,通过重新计算一个文件的哈希并将其与一个已知的良好值进行比较,我们可以以近乎完美的确定性验证其完整性。
数字签名(不可伪造的印章): 哈希告诉你文件是否被更改,但不能告诉你它来自谁。为此,我们使用基于非对称密码学的数字签名。软件供应商,如 Microsoft 或 Apple,会生成一对密钥:一个私钥(他们会用生命来守护),以及一个公钥(他们会自由分发)。他们通过获取其软件的哈希值并用其私钥加密来“签名”其软件。这个签名与软件捆绑在一起。
现在,让我们把它们整合起来。不可变的引导 ROM 包含供应商的公钥 ()。当计算机开启时,ROM 代码会执行以下流程:
现在受信任的固件,对下一阶段——操作系统引导加载程序,重复完全相同的过程,而引导加载程序又会验证操作系统内核。链中的每一环在传递接力棒之前都会以加密方式验证下一环。在某些系统上,这甚至在微架构层面被强制执行。一个特殊的硬件开关,我们称之为 fetch_en 位,可以在物理上阻止处理器的指令提取单元在验证完成前从不受信任的内存中读取代码。这是一座数字吊桥,在新来者的凭证被彻底检查之前,它会一直保持升起状态。整个过程当然需要时间,而哈希引导镜像的速度通常是决定您等待计算机启动时间的瓶颈。
您可能会想,所有这些密码学的复杂性真的有必要吗?更简单的检查方法怎么样?几十年来,计算机一直使用奇偶校验位来检测内存中的错误。奇偶校验位是添加到一块数据中的一个额外位,指示该数据中 1 的数量是偶数还是奇数。如果一个随机的宇宙射线在传输过程中翻转了一个位,奇偶性将不再匹配,错误就会被检测到。
为什么我们不能就用这个来进行安全启动呢?让我们想象一下,我们在安全 ROM 中存储了引导加载程序每个块的正确奇偶校验值。在启动时,我们重新计算奇偶校验值并进行检查。这将保护我们免受随机噪声的影响。但我们对抗的不是噪声,而是一个智能的对手。
攻击者可以修改引导加载程序代码以插入他们的恶意软件。这很可能会改变奇偶性。但攻击者随后可以简单地在同一块中的其他地方翻转另一个任意位。两个位的翻转恢复了原始的奇偶性!现在,这个包含偶数个错误的更改,对于奇偶校验来说是完全不可见的。攻击者制造了一个恶意文件,在我们简单的检查看来是完全有效的。
这精妙地说明了纠错码(如奇偶校验)和加密哈希函数之间的区别。加密哈希被设计为抗碰撞的,这意味着对于攻击者来说,在计算上不可能有意创建一个与合法文件具有相同哈希值的恶意文件。这种稳健性不是一种奢侈品,它是软件安全的绝对基础。
那么,我们的信任链验证了每个软件组件都是真实的,并且没有被篡改。我们安全了吗?不完全是。如果攻击者不是试图伪造新软件,而是用一个旧版本替换您那崭新、打满补丁的操作系统——一个多年前由供应商合法签名,但现在已知存在严重安全漏洞的版本呢?签名是完全有效的。信任链会检查通过,而您将在不知不觉中启动一个易受攻击的系统。
这被称为回滚攻击。为了抵御它,我们的安全启动过程不仅需要检查真实性,还需要检查时效性。这通过另外两个组件来完成:每个签名的软件都被赋予一个版本号,并且计算机芯片包含一个称为单调计数器的特殊硬件。
单调计数器就像汽车的里程表:它只能增加(或保持不变);它永远不能回滚到更低的数字。当一个新的软件组件被验证时,引导代码会检查它的版本号 是否大于或等于当前存储在单调计数器中的版本。如果检查通过,系统就会将计数器更新为 。这确保了没有人能够欺骗系统加载一个比它所见过的最新版本更旧的软件版本。
到目前为止我们描述的过程通常被称为安全启动。它是一种强制执行的策略。如果链中的任何组件无效——签名错误、哈希值不符、版本过旧——启动过程就会停止。它就像俱乐部里的保镖,检查身份证件,拒绝任何不在名单上的人。
但还有一个相辅相成的、同样强大的概念,叫做度量启动。与其仅仅阻止不良行为者,我们是否也可以 meticulous地、不可伪造地记录下所有加载的东西,无论它是好的、坏的,还是仅仅是意料之外的?
这是可信平台模块 (TPM) 的工作,它是主板上的一个专用安全协处理器。TPM 包含一组称为平台配置寄存器 (PCR) 的特殊寄存器。您不能简单地向 PCR 中写入一个值。您只能执行扩展 (extend) 操作。此操作获取 PCR 的当前值,将其与新数据(一次“度量”)连接起来,然后对结果进行哈希以生成新的 PCR 值:
由于加密哈希的特性,这个过程是单向的。最终的 PCR 值是扩展到其中的所有度量的精确序列的唯一签名,并且顺序也完全一致。您无法撤销一个步骤或在中间插入一个步骤而不改变最终结果。
在度量启动期间,启动过程的每个阶段——从引导 ROM 开始——在执行下一个阶段之前都会对其进行度量(通过哈希),并将该度量扩展到一个 PCR 中。结果是一份可加密验证的、完整的引导链记录。
这个区别通过一个实际例子变得清晰。想象一个攻击者修改了内核的引导配置——例如,一个禁用了关键安全功能的命令行选项。安全启动,在其最常见的形式下,可能不会阻止这个。内核的代码没有改变,所以它的签名仍然有效。配置只是传递给它的数据。安全启动这个保镖会让它进来。
然而,度量启动就像一个公证人。引导加载程序被配置为不仅度量内核代码,还度量命令行字符串。由于命令行已更改,度量结果将会不同,最终的 PCR 值也会不同。这一变化被不可磨灭地记录下来。虽然机器启动了,但执行远程证明的远程服务器可以向 TPM 请求 PCR 值。当服务器看到该值与安全配置系统的“黄金”值不匹配时,它就知道该机器已偏离其可信状态,并可以阻止它访问网络 [@problemid:3679609]。安全启动对可执行代码强制执行策略;度量启动为系统的状态(包括代码和配置)提供证据。
信任链已成功验证了操作系统内核。引导加载程序的最后一项任务是将控制权交给它。但这是一个至关重要的时刻。整个引导过程一直运行在处理器最高权限模式下,可以无限制地访问所有硬件。而操作系统,尤其是用户应用程序,必须在低得多的权限下运行。
引导加载程序的最后一项工作是为操作系统建立一个安全和受保护的环境。它遵循最小权限原则。在进行跳转之前,它会配置处理器的内存管理单元 (MMU)。它创建一个内存映射——页表——来定义交通规则。代码区域被标记为只读和可执行。数据区域(如堆栈和堆)被标记为可读写,但关键的是,不可执行 (NX)。这个小小的 NX 位是一项强大的防御措施,因为它能阻止一大类涉及欺骗程序执行攻击者提供的恶意数据的攻击。
这个顺序对于避免检查时到使用时 (TOCTOU) 的竞态条件至关重要。在仍处于最高权限模式时,引导加载程序必须:
这确保了内核在运行时绝不会有哪怕一微秒的时间没有其内存保护盔甲完全就位。
安全启动过程是一个宏伟的信任架构,但它并非万无一失。它的安全性完全依赖于其最早环节的完整性。如果锚点本身——固件——被攻破了会发生什么?
感染 UEFI 固件的恶意软件被称为 bootkit。即使您完全重装操作系统或更换硬盘,这类恶意软件也能持续存在,因为它存在于主板上的一个芯片中。被攻破的固件可以破坏整个信任链。它可以撒谎。它可以向 TPM 呈现一个良好内核的有效度量值,但随后却将一个恶意的内核加载到内存中。如果进行度量的主体本身不可信,那么度量值本身也就毫无价值。
安全永远是一条链,它的强度取决于其最薄弱的一环。安全启动过程证明了,要锻造一条从第一束电流火花开始就坚固无比的链条,需要付出巨大的努力,从而创建一个信任的基础,整个复杂的现代计算世界都可以在其上构建。
在经历了安全启动和度量启动的基础原理之旅后,我们可能会留下一个印象,即这是一个复杂但优雅的安全机制。但这只是故事的开始。就像新发现的物理定律一样,信任链的真正力量和美丽并非在孤立中显现,而是在其广泛多样的应用中得以揭示。它是一个从嵌入式芯片最深层的硅片到全球云的短暂架构中都能产生回响的概念。它不仅仅是一个功能清单上的待办项;它是在一个 inherently 不可靠的世界中构建可靠系统的基本模式。
现在,让我们探讨这条信任链将我们引向何方,看看它如何解决现实世界的问题,创造新的可能性,并与我们可能从未预料到的领域产生联系。
在最直接的层面上,安全启动过程充当我们日常交互的计算机的不眨眼的卫士。它的首要职责是确保您打开的设备与您关闭时的设备相同,没有受到篡改或启动前感染。
考虑一下现代个人电脑,一个通常需要运行多个操作系统的复杂生态系统。我们如何信任一台同时启动 Windows 和 Linux 的机器?信任链提供了答案。当机器启动 Windows 时,UEFI 固件会验证经微软签名的引导加载程序。当您选择启动 Linux 时,固件会加载一个由微软签名的微小的 "shim" 加载程序。这个 shim 并不代表信任链的中断,而是信任的委托。固件信任 shim,而 shim 则被设计为根据由用户或 Linux 发行版控制的另一组密钥——机器所有者密钥 (MOKs)——来验证下一阶段的引导加载程序(如 GRUB)。这种优雅的交接在保持连续、可验证的加密链的同时,也提供了灵活性。然而,这条链的强度取决于其最薄弱的一环。如果 GRUB 引导加载程序被配置为加载一个未经签名验证的 Linux 内核,那么即使前面的每一步都是安全的,强制执行链在这一点上也断裂了。
这揭示了一个关于安全的深刻真理:它是一个过程,而不是一个静态属性。安全启动的原则必须在每个阶段都得到坚持。这也是为什么操作系统内的管理控制权并不等同于对机器的完全控制。一个在大学实验室电脑上拥有管理员权限的学生可以修改任何他想要的文件,但他不能让机器启动一个未经授权的内核,因为他无法伪造固件所要求的签名,而固件的密钥由机构控制。在操作系统苏醒之前,卫士就已经在岗了。
同样的原则也延伸到我们看不见的无数计算机上,甚至可能更为关键。您的汽车、医疗设备或工业控制器都是计算机。如果您的汽车引擎控制单元的固件更新因断电而中断会发生什么?结果可能是一辆“变砖”的汽车。我们如何防止攻击者将固件降级到一个旧的、易受攻击的版本?解决方案是硬件和软件的精妙互动。系统通常使用 A/B 分区方案,将新更新写入非活动分区,而旧的、工作正常的版本保持不变。只有在新固件完全写入、经过加密验证并成功测试启动后,系统才会确认这一更改。反回滚保护通常由一种物理的、不可逆的机制来强制执行:电子熔丝 (eFuse)。通过在 eFuse 组中烧写一个额外的位来增加版本计数器,系统做出了永久性的承诺。就像一个只能向前转动的棘轮,硬件本身现在拒绝启动任何比新建立的版本更旧的软件,为信任链提供了一个物理锚点。
当我们超越单一、孤立的设备,进入一个互联系统的世界时,信任链的力量才真正闪耀。我们如何信任大型组织或数据中心中的设备,尤其是当它们通过不安全的网络启动时?
在企业环境中,IT 部门必须强制执行安全策略。例如,他们需要允许技术人员从经批准的、特殊签名的 USB 维护工具启动,但要防止员工从停车场撿到的随机 U 盘启动恶意的操作系统。UEFI 固件成为策略执行点。通过精心管理签名数据库 (),使其只信任企业签名的密钥,并移除通用的第三方密钥,组织可以精确地强制规定谁被允许启动。一个最新的吊销列表 () 提供了第二层防御,允许立即将任何被泄露的密钥或恶意程序列入黑名单。
当一台机器完全没有本地磁盘,必须使用预启动执行环境 (PXE) 通过网络启动时,挑战会加剧。标准的 PXE 协议 DHCP 和 TFTP 是在隐式信任的时代设计的,不提供任何安全性;本地网络上的攻击者可以轻易地欺骗响应,并向正在启动的客户端提供一个恶意的操作系统。在这里,安全启动过程可以与其他协议层叠,以在不安全的通道上建立一座信任之桥。一种现代方法要求初始的网络引导程序 (NBP) 必须由客户端的 UEFI 安全启动进行签名和验证。这个受信任的 NBP 随后可以拒绝使用普通的 TFTP,而是通过像 TLS 这样的安全通道获取所有后续的引导构件,并锁定服务器的证书以确保它正在与合法的配置服务器通信。整个过程通过度量启动被记录下来。每个构件的哈希,甚至可信服务器证书的哈SH,都被扩展到 TPM 的平台配置寄存器 (PCR) 中。这创建了一个不间断的、可验证的记录,不仅证明了什么被启动,还证明了它是从一个可信的来源通过安全通道加载的,从而挫败了基于网络的攻击。
在任何地方,可验证的信任链概念都没有比在云计算中更为关键。当您在公共云上运行虚拟机 (VM) 时,您是在别人的计算机上运行您的软件。您机器的根基本身就是软件——hypervisor。您怎么可能信任它呢?
安全启动和度量启动的原则被扩展到这个虚拟世界。在物理硬件上安全启动的 hypervisor,为客户 VM 扮演了“虚拟固件”的角色。它加载客户自己的虚拟固件(如 OVMF)并启动客户的引导过程。客户的度量信任根 () 现在是在 VM 内部运行的第一段代码,它将一个度量链启动到一个呈现给客户的虚拟 TPM (vTPM) 中。客户的可信计算基 ()——它必须信任的组件集——现在隐含地包括了主机的 TCB:hypervisor、物理硬件,以及像 IOMMU 这样隔离 VM 的机制。这种虚拟化环境引入了新的风险,例如通过微架构侧信道(如共享的 CPU 缓存)的信息泄漏,这些风险存在于安全启动的逻辑模型之外,需要不同的缓解策略。
那么,租户如何能确定他们的 VM 运行的是正确的代码,并且没有被恶意的或被攻破的 hypervisor 篡改?答案是远程证明,一场极其优雅的加密之舞。租户的验证者向 VM 发送一个挑战——一个随机数 (nonce)。在 VM 内部,一个请求被发送到它的 vTPM 以生成一个“引用” (quote):一个包含当前 PCR 值和验证者随机数的签名声明。这个引用由一个独特的证明密钥 (AK) 签名,该密钥本身是一个证书链的一部分,该证书链可以追溯到物理硬件 TPM,甚至可以包括 VM 的唯一实例 ID。VM 将这个签名的引用、事件日志和证书链发送回验证者。验证者随后可以检查签名以确认引用来自真实的硬件,检查随机数以确保引用是新鲜的而不是重放攻击,并根据事件日志重新计算 PCR 值,以验证整个引导链——从虚拟固件到内核——都与预期的“黄金”状态匹配。只有在这种完整性的加密证明之上,验证者才会向 VM 释放敏感的秘密,如磁盘加密密钥。这个过程是机密计算的基石,使得在零信任环境中建立信任成为可能 [@problemid:3689858]。
信任链不仅仅是一道防御墙;它催生了全新的能力,并为我们系统的架构本身提供了信息。
想象一个安全事件已经发生。攻击者可能已经入侵了一个系统,然后通过修改磁盘上的日志来掩盖他们的踪迹。调查员如何重建引导过程中真正发生了什么?度量启动的事件日志,当与 TPM 进行验证时,就像系统引导过程的一个不可腐蚀的“黑匣子飞行记录仪”。因为存储在 TPM 中的 PCR 值是单向加密函数的结果,所以拥有操作系统级别控制权的攻击者无法伪造它们。调查员可以向 TPM 请求一个签名的引用,以获取真实的最终 PCR 值。然后他们可以从磁盘上获取事件日志并对其进行“重放”,通过计算重新生成 PCR。如果重新计算的值与引用的值匹配,那么日志就被证明是引导过程的真实记录。如果不匹配,则说明日志已被篡改。这为取证专家提供了一个植根于硬件的真相锚点,他们可以从此开始调查,从而准确识别在引导过程中执行了哪些代码,无论是恶意的还是其他的。
最后,这些原则反馈到安全操作系统的基本设计中。安全的一个核心原则是最小化 TCB。例如,在微内核架构中,设备驱动程序被移出特权内核,进入沙盒化的用户空间进程中。这似乎是安全上的一个明显胜利。然而,仅靠虚拟内存保护是不够的。驱动程序需要硬件隔离(通过 IOMMU 来监管 DMA)以及内核对其权限的仔细仲裁。驱动程序现在在 TCB 之外,因为它的一个 bug 不会使内核崩溃,但它值得信赖吗?为了确保运行的是正确、已知的良好驱动程序,微内核必须做的不仅仅是启动它;它必须将授权与身份绑定。它通过在授予驱动程序访问其设备所需的能力之前,根据可信策略检查驱动程序的加密度量(或签名)来实现这一点。这种构建最小化、可信组件的模式,对于创建紧急系统(如必须被信任用于修复损坏的操作系统而自身不成为安全风险的恢复控制台)也至关重要。
“先度量,后执行”这一简单理念,从一个信任根开始环环相扣,已被证明是现代计算机安全中最强大、最通用的概念之一。它证明了简单、可组合的加密断言如何能够构建起信任的堡垒,从最小的传感器到最大的云。它是那个沉默的、永远在场的守护者,让我们能够构建一个更可预测、更可靠的数字世界。