在前面的章节中,我们讨论了软件层面的安全机制:访问控制、认证、加密、协议等。但这些机制都假设底层硬件和系统是可信的。如果硬件或系统本身不可信,上层的安全机制可能形同虚设。这就像是建造一座大楼,如果地基不牢固,无论上面的建筑多么精美,都可能倒塌。
可信计算(Trusted Computing)关注如何建立从硬件到软件的可信链,确保系统从启动到运行的整个过程中都是可信的。

可信计算是安全系统的基础。如果底层系统不可信,上层的安全机制可能无法提供真正的安全。理解可信计算有助于理解现代安全架构。这就像是信任的基础,如果基础不可信,整个信任体系就会崩塌。
这一部分我们将讨论可信系统的定义、可信启动、硬件辅助安全、信任链等核心概念。
什么是“可信”?在安全领域,“可信”并不意味着“安全”,而是意味着“可以依赖”。一个可信系统是我们可以依赖其行为的系统,即使它可能不是完全安全的。这听起来有点矛盾,但理解这个区别很重要。
“可信”和“安全”是两个不同的概念,但它们经常被混淆。安全意味着系统没有漏洞,不会被攻击。可信意味着系统会按照预期行为,即使它可能不安全。
让我用一个比喻来说明。想象一下,你有一个朋友,他非常诚实,总是说真话。这个朋友是可信的,因为你可以依赖他的话。但如果这个朋友不知道某个问题的答案,他可能会说“我不知道”,这是可信的,但不是安全的(因为信息可能不准确)。另一方面,如果你有一个朋友,他知道很多信息,但他经常说谎。这个朋友可能知道正确答案,但不可信,因为你不能依赖他的话。
在计算机系统中,一个系统可能是可信的,但不是安全的。比如,一个系统可能按照设计工作,但设计本身有缺陷,导致系统容易被攻击。或者一个系统可能是安全的,但不是可信的。比如,一个系统可能没有漏洞,但我们不能确定它的行为,因为我们不知道它是否被修改过。
理解“可信”和“安全”的区别很重要。可信计算关注的是建立可信的系统,而不是完全安全的系统。即使系统是可信的,它仍然可能被攻击。但如果我们知道系统是可信的,我们可以依赖它的行为,这对于建立安全系统很重要。
可信计算基(Trusted Computing Base,TCB)是系统中必须可信才能保证系统安全的部分。TCB包括硬件、固件、操作系统内核、安全相关的软件等。这就像是安全系统的核心,如果核心不可信,整个系统就不可信。
TCB应该尽可能小,因为TCB中的任何漏洞都可能影响整个系统的安全性。这就像是尽量减少需要信任的人的数量,如果只有少数几个人需要信任,那么风险就更小。但TCB太小可能影响系统功能,需要在安全性和功能性之间找到平衡。
在实际设计中,我们需要仔细考虑哪些组件应该包含在TCB中。通常,我们会将最关键的组件包含在TCB中,比如硬件、固件、操作系统内核等。其他组件,比如应用程序,可能不在TCB中,但它们的行为仍然受到TCB的保护。
信任边界定义了信任的范围。在信任边界内,我们假设系统是可信的。在信任边界外,我们假设系统是不可信的。这就像是房子的围墙,围墙内是可信的,围墙外是不可信的。
确定信任边界是安全设计的关键。信任边界应该尽可能小,只包括必要的组件。这就像是尽量减少房子的面积,如果房子越小,需要保护的边界就越小。但信任边界太小可能影响系统功能,需要在安全性和功能性之间找到平衡。
在实际设计中,我们通常会将硬件和固件放在信任边界内,因为它们是最基础的组件。操作系统内核可能也在信任边界内,因为它控制着系统的核心功能。应用程序通常不在信任边界内,但它们的行为受到信任边界内组件的保护。
可信启动(Trusted Boot)确保系统从启动到运行的整个过程中都是可信的。可信启动通过验证每个启动阶段的完整性来建立信任链。这就像是检查一条链条的每一个环节,确保每个环节都是完整的,整条链条才是可信的。
计算机启动过程包括多个阶段,每个阶段都可能被攻击。如果任何阶段被修改,后续阶段可能不可信。这就像是接力赛,每一棒都必须正确传递,如果任何一棒出错,整个比赛就失败了。
首先是BIOS/UEFI阶段。这是系统启动的第一步,它初始化硬件,然后加载引导加载程序。如果BIOS/UEFI被修改,它可能加载恶意的引导加载程序,导致整个系统被攻破。
接下来是引导加载程序阶段。引导加载程序(如GRUB、Windows Boot Manager)加载操作系统内核。如果引导加载程序被修改,它可能加载恶意的内核,导致系统被攻破。
然后是操作系统内核阶段。内核是操作系统的核心,它控制着系统的所有资源。如果内核被修改,攻击者可能获得系统的完全控制。
接下来是系统服务阶段。系统服务是操作系统提供的服务,比如网络服务、文件服务等。如果系统服务被修改,攻击者可能通过这些服务来攻击系统。
最后是应用程序阶段。应用程序是用户使用的程序,它们运行在操作系统之上。如果应用程序被修改,攻击者可能通过这些应用程序来攻击系统。
每个阶段都可能被攻击,所以我们需要验证每个阶段的完整性,确保它们没有被修改。
可信启动通过验证每个启动阶段的完整性来实现。有几种方法可以实现可信启动,每种方法有不同的特点。
安全启动(Secure Boot)使用数字签名验证每个启动阶段的完整性。只有经过签名的代码才能执行,未签名的代码会被阻止。这就像是检查每个人的身份证,只有有合法身份证的人才能进入。安全启动可以防止启动阶段的恶意代码执行,但需要管理签名密钥,这可能很复杂。
可信启动(Trusted Boot)使用TPM(Trusted Platform Module)存储启动阶段的度量值。启动过程中,每个阶段的代码被测量(计算哈希值),度量值被存储到TPM中。这就像是记录每个环节的状态,如果任何环节被修改,记录就会改变,我们可以检测到。可信启动不阻止启动,只记录启动过程的完整性,所以即使启动过程被修改,系统仍然会启动,但我们可以检测到修改。
测量启动(Measured Boot)类似于可信启动,但它不阻止启动,只测量和记录。这可以用于远程证明,向远程方证明系统的完整性。
可信启动提供了从硬件到软件的可信链。如果启动过程是可信的,我们可以相信系统从启动开始就是可信的。这就像是建立了一条可信的链条,从硬件开始,一直延伸到应用程序。

安全启动(Secure Boot)是UEFI的一个功能,使用数字签名验证启动代码的完整性。只有经过签名的代码才能执行,未签名的代码会被阻止。这就像是建立一个白名单,只有名单上的代码才能执行。
安全启动的工作流程是这样的。首先,UEFI固件验证引导加载程序的签名。如果签名有效,引导加载程序就可以执行。然后,引导加载程序验证操作系统内核的签名。如果签名有效,内核就可以执行。接下来,内核验证驱动程序和系统服务的签名。最后,系统服务可以验证应用程序的签名(这是可选的)。
安全启动防止了启动阶段的恶意代码执行,但需要管理签名密钥,这可能很复杂。我们需要确保只有合法的代码被签名,而且签名密钥不能被泄露。如果签名密钥泄露,攻击者可能签名恶意代码,绕过安全启动。
可信启动(Trusted Boot)使用TPM来存储启动阶段的度量值。启动过程中,每个阶段的代码被测量(计算哈希值),度量值被存储到TPM的PCR(Platform Configuration Register)中。
可信启动不阻止启动,只记录启动过程的完整性。如果启动过程被修改,度量值会改变,系统可以检测到。这就像是记录每个环节的状态,如果任何环节被修改,记录就会改变。
可信启动可以用于多个目的。首先是远程证明,系统可以向远程方证明其完整性。远程方可以检查TPM中的度量值,验证系统是否可信。其次是合规性检查,系统可以检查自己是否符合安全策略。最后是事件调查,当安全事件发生时,我们可以检查TPM中的度量值,了解系统在事件发生时的状态。
硬件辅助安全使用专用硬件来提供安全功能。硬件辅助安全比软件安全更可靠,因为硬件更难被攻击。这就像是把重要的东西放在保险箱里,而不是放在普通的抽屉里。
TPM是可信计算的核心硬件。TPM是一个独立的硬件芯片,与主处理器隔离,这提供了更强的安全性,因为即使主处理器被攻破,TPM仍然安全。这就像是有一个独立的保险箱,即使房子被攻破,保险箱仍然安全。
TPM提供多种安全功能。首先是安全存储,TPM可以安全地存储密钥和证书。这些密钥和证书受到硬件保护,即使软件被攻破,它们仍然安全。其次是加密功能,TPM可以提供硬件加密和解密,这比软件加密更安全、更快速。第三是随机数生成,TPM可以提供密码学安全的随机数,这对于生成密钥很重要。第四是平台配置寄存器(PCR),TPM可以存储系统状态的度量值,用于验证系统完整性。最后是远程证明,TPM可以向远程方证明系统完整性。
TPM提供了硬件级的安全功能。即使软件被攻破,TPM仍然可以提供安全存储和加密功能。这是可信计算的基础。在实际应用中,TPM被广泛用于全盘加密、安全启动等功能。

TPM可以用于全盘加密。加密密钥存储在TPM中,只有TPM可以访问。如果系统启动过程是可信的,TPM会释放密钥,系统可以解密磁盘。如果启动过程被修改,TPM不会释放密钥,系统无法启动。
这提供了强大的数据保护。即使攻击者获得了物理访问,如果启动过程被修改,他们也无法解密磁盘。这就像是把钥匙放在一个需要密码的保险箱里,即使攻击者获得了保险箱,如果不知道密码,也无法打开。
在实际应用中,BitLocker(Windows)和FileVault(macOS)都使用TPM来保护加密密钥。当系统启动时,TPM验证启动过程的完整性,如果启动过程是可信的,TPM释放密钥,系统可以解密磁盘。如果启动过程被修改(比如被恶意软件修改),TPM不会释放密钥,系统无法启动,数据受到保护。
Intel TXT(Trusted Execution Technology)和AMD SVM(Secure Virtual Machine)是硬件虚拟化安全技术。它们提供了虚拟化环境中的安全保护。
这些技术可以验证虚拟机监控器的完整性。虚拟机监控器是虚拟化系统的核心,如果它被攻破,所有虚拟机都可能被攻破。通过验证虚拟机监控器的完整性,我们可以确保虚拟化环境是可信的。
这些技术还可以保护虚拟机内存不被其他虚拟机访问。在虚拟化环境中,多个虚拟机共享物理硬件,如果内存保护不当,一个虚拟机可能访问另一个虚拟机的内存。这些技术提供了硬件级的内存保护,确保虚拟机之间的隔离。
Intel SGX(Software Guard Extensions)允许应用程序创建受保护的内存区域(Enclave)。Enclave中的代码和数据受到硬件保护,即使操作系统或虚拟机监控器被攻破,Enclave仍然安全。这就像是创建一个独立的保险箱,即使房子被攻破,保险箱仍然安全。
SGX可以用于多个目的。首先是数据保护,SGX可以保护敏感数据不被操作系统访问。即使操作系统被攻破,攻击者也无法访问Enclave中的数据。其次是代码保护,SGX可以保护代码不被逆向工程。即使攻击者获得了内存转储,他们也无法理解Enclave中的代码。最后是远程证明,SGX可以向远程方证明代码的完整性。
但SGX也有局限性。SGX可能受到侧信道攻击,攻击者可能通过观察系统的物理特性(如执行时间、功耗)来获取信息。而且SGX的性能可能影响应用程序性能,因为每次访问Enclave都需要切换到受保护模式。
信任链(Chain of Trust)是建立系统可信性的方法。信任链从最可信的组件开始,逐步扩展到整个系统。这就像是建立一条信任的链条,每个环节都验证下一个环节,确保整条链条都是可信的。
信任根(Root of Trust)是信任链的起点。信任根必须是可信的,因为整个信任链都依赖于它。这就像是链条的第一个环节,如果第一个环节不可信,整条链条就不可信。
信任根可能包括硬件信任根(如TPM、安全启动芯片)、固件信任根(如BIOS、UEFI)、软件信任根(如引导加载程序、操作系统内核)等。信任根应该尽可能小,因为信任根中的任何漏洞都可能影响整个信任链。这就像是尽量减少需要信任的人的数量,如果只有少数几个人需要信任,那么风险就更小。
在实际设计中,我们通常会将硬件作为信任根,因为硬件是最基础的组件,而且硬件更难被攻击。然后,硬件验证固件的完整性,固件验证引导加载程序的完整性,引导加载程序验证内核的完整性,以此类推,建立信任链。
信任链的建立过程是这样的。首先,硬件提供初始信任。硬件是信任链的起点,我们假设硬件是可信的(虽然这可能不总是成立,但我们需要一个起点)。
然后,固件验证引导加载程序的完整性。固件使用数字签名或其他方法验证引导加载程序,确保它没有被修改。如果验证通过,引导加载程序就可以执行。
接下来,引导加载程序验证操作系统内核的完整性。引导加载程序使用数字签名或其他方法验证内核,确保它没有被修改。如果验证通过,内核就可以执行。
然后,内核验证驱动程序和系统服务的完整性。内核使用数字签名或其他方法验证驱动程序和系统服务,确保它们没有被修改。如果验证通过,驱动程序和系统服务就可以执行。
最后,系统服务可以验证应用程序的完整性(这是可选的)。系统服务可以使用数字签名或其他方法验证应用程序,确保它们没有被修改。如果验证通过,应用程序就可以执行。
每个阶段验证下一个阶段的完整性,建立信任链。如果任何阶段被修改,验证就会失败,信任链就会断裂。
信任链的强度取决于最弱的环节。如果任何环节被攻破,整个信任链可能失效。设计信任链时,需要确保每个环节都是安全的。这就像是链条的强度取决于最弱的环节,如果任何一个环节断裂,整条链条就会断裂。
BitLocker是Windows的全盘加密功能,使用TPM来保护加密密钥。BitLocker的工作流程是这样的。首先,系统启动时,TPM验证启动过程的完整性。如果启动过程是可信的,TPM释放加密密钥。然后,系统使用密钥解密磁盘。最后,系统正常运行。
如果启动过程被修改(比如被恶意软件修改),TPM不会释放密钥,系统无法启动,数据受到保护。这提供了强大的数据保护,即使攻击者获得了物理访问,如果启动过程被修改,他们也无法解密磁盘。
在实际使用中,BitLocker可以保护笔记本电脑的数据。如果笔记本电脑丢失或被盗,即使攻击者获得了物理访问,如果启动过程被修改(比如试图从USB启动),TPM不会释放密钥,攻击者无法解密磁盘。
Secure Boot是UEFI的安全启动功能,使用数字签名验证启动代码。Secure Boot防止了启动阶段的恶意代码执行,提供了从硬件到软件的可信链。
在实际使用中,Secure Boot可以防止Bootkit等恶意代码。Bootkit是启动阶段的恶意代码,它可以在操作系统启动之前执行,因此很难被检测和移除。Secure Boot可以防止Bootkit执行,因为它会验证启动代码的签名,只有经过签名的代码才能执行。
远程证明(Remote Attestation)允许远程方验证系统的完整性。系统使用TPM来证明其完整性,远程方可以验证系统是否可信。
远程证明可以用于多个场景。首先是云服务,云服务提供商可以向客户证明其系统的完整性。客户可以验证云服务提供商的系统是否可信,确保他们的数据是安全的。其次是企业网络,企业可以验证连接到网络的系统的完整性。如果系统不可信,企业可以拒绝连接,或者限制访问。最后是合规性,系统可以证明自己符合安全策略,满足合规性要求。

如果信任根(如硬件、固件)不安全,整个信任链可能失效。但信任根可能难以更新或修复,如果发现漏洞,可能无法修复。这就像是如果房子的地基有问题,修复起来会很困难。
在实际应用中,我们曾经见过硬件漏洞,比如Spectre和Meltdown。这些漏洞存在于硬件中,很难修复,可能需要更换硬件。而且即使我们修复了硬件,如果固件有漏洞,整个信任链仍然可能失效。
即使系统是可信的,它仍然可能受到侧信道攻击。侧信道攻击通过观察系统的物理特性(如执行时间、功耗、电磁辐射)来获取信息。这就像是通过观察一个人的行为来推断他的想法,即使这个人不说,我们也可以通过观察来获取信息。
在实际攻击中,攻击者可能通过观察系统的执行时间来推断密钥,或者通过观察系统的功耗来推断操作。这些攻击很难防御,因为它们不依赖于系统的逻辑漏洞,而是依赖于系统的物理特性。
如果硬件或软件的供应链被攻击,即使系统是可信的,它仍然可能不安全。供应链攻击特别危险,因为用户信任硬件或软件的来源,可能不会怀疑其安全性。
在实际攻击中,我们曾经见过供应链攻击,比如SolarWinds事件。攻击者感染了软件更新,当用户安装更新时,后门也被安装。即使系统使用了可信计算,如果软件更新本身被感染,可信计算也无法保护系统。
可信计算增加了系统复杂性。管理签名密钥、验证信任链、处理更新等都需要额外的努力。而且如果配置不当,可信计算可能无法提供预期的保护,甚至可能影响系统功能。
在实际部署中,我们需要仔细配置可信计算,确保它能够提供预期的保护,同时不会过度影响系统功能。这需要专业的知识和经验,不是所有组织都有这样的能力。
可信计算关注如何建立从硬件到软件的可信链。可信启动确保系统从启动到运行的整个过程中都是可信的,硬件辅助安全使用专用硬件来提供安全功能,信任链从信任根开始,逐步扩展到整个系统。
在下一节课中,我们将讨论程序安全,理解如何编写安全的程序,以及如何防御程序级攻击。