什么是 TEE?TEE 的安全模型?常见的 TEE 漏洞及其安全实践指南。
原文标题:《Securing TEE Apps: A Developer's Guide》
撰文:prateek, roshan, siddhartha & linguine (Marlin), krane (Asula)
编译:Shew,仙壤 GodRealmX
自从 Apple 宣布推出私有云以及 NVIDIA 在 GPU 中提供机密计算以来,可信执行环境(TEE)变得越来越流行。它们的机密性保证有助于保护用户数据(可能包括私钥),而隔离性确保部署在其上的程序的执行不会被篡改——无论是人类、其他程序还是操作系统。因此,Crypto x AI 领域大量使用 TEE 构建产品也不足为奇。
与任何新技术一样,TEE 正在经历一段乐观的实验期。本文希望为开发人员和一般读者提供基础的概念指南,让他们了解什么是 TEE、TEE 的安全模型、常见的漏洞和安全使用 TEE 的最佳实践方式。(注意:为了使文本易于理解,我们有意识地用更简单的等价词替换了 TEE 术语)。
TEE 是处理器或数据中心中的隔离环境,程序可以在其中运行,而不会受到系统其余部分的任何干涉。为了避免 TEE 被其他部分干涉,我们需要一系列的设计,主要包括严格的访问控制,即控制系统其他部分对 TEE 内程序和数据的访问。目前 TEE 在手机、服务器、PC 和云环境中无处不在,因此非常易于访问且价格合理。
上面的内容听起来可能很模糊和抽象,实际上不同的服务器和云供应商实施 TEE 的方式不同,但其根本目的是为了避免 TEE 被其他程序干涉。
大多数读者可能会用生物识别信息登录设备,比如通过指纹解锁手机。但我们如何保证恶意应用程序、网站或越狱操作系统无法访问和窃取这些生物识别信息?事实上,除了把数据加密之外,TEE 设备中的电路根本不允许任何程序访问敏感数据占用的内存和处理器区域。
硬件钱包是 TEE 应用场景的另一个示例。硬件钱包连接到计算机并与其进行沙盒通信,但计算机无法直接访问硬件钱包内存储的助记词。在上述两种情况下,用户都相信设备制造商能够正确设计芯片并提供适当的固件更新,以防止 TEE 内的机密数据被导出或查看。
遗憾的是,TEE 实现种类非常多,这些不同的实现(IntelSGX、IntelTDX、AMDSEV、AWSNitroEnclaves、ARMTrustZone)都需要独立的安全模型建模分析。在本文的其余部分,我们将主要讨论 IntelSGX、TDX 和 AWSNitro,因为这些 TEE 系统具有较多的用户,也具有完整可用开发工具。上述系统也是 Web3 内最常用的 TEE 系统。
一般而言,在 TEE 中部署的应用程序的工作流如下:
显然,这里面有 3 个潜在的风险:
值得庆幸的是,现在的 TEE 已经有了消除上述风险的方案,即可重复构建 (Reproducible Builds) 和远程证明 (Remote Atteststations)。
那么什么是可重复构建?现代软件开发往往需要导入大量依赖,比如外部工具、库或框架等,这些依赖文件也可能存在隐患。现在 npm 等方案使用了依赖文件对应的代码哈希作为唯一标识符。当 npm 发现某个依赖文件与记录的哈希值不一致时,就可以认为该依赖文件已被修改。
而可重复构建可以被认为是一组标准,目标是当任意代码在任何设备上跑时,只要按照事先规定的流程进行构建,最终都可以得到一致的哈希值。当然,在实操中我们也可以使用哈希之外的产物作为标识符,此处我们称之为代码度量 (code measurement)。
Nix 是可重复构建的常用工具。当程序的源码公开后,任何人都可以检查代码,以确保开发人员没有插入异常内容,任何人都可以使用 Nix 构建代码,检查构建出的产物是否与项目方在生产环境中部署的产物有相同的代码度量 /Hash。但我们如何知道 TEE 中程序的代码度量值呢?这里就涉及到称为「远程证明」的概念。
远程证明是来自 TEE 平台(受信任方)的签名消息,其中包含程序的代码度量值、TEE 平台版本等。远程证明让外部观察者知道,某个程序正在任何人都无法访问的安全位置(xx 版本的真实 TEE)中执行。
可重复构建和远程证明使得任何用户都可以知道 TEE 内运行的实际代码和 TEE 平台版本信息,从而防止开发者或者服务器作恶。
但是,在 TEE 的情况下,始终需要信任其供应商。如果 TEE 供应商作恶,可以直接伪造远程证明。因此,如果将供应商视为可能的攻击媒介,应避免仅依赖 TEE,最好将它们与 ZK 或共识协议相结合。
在我们看来,TEE 特别受欢迎的特性,尤其是对于 AI Agent 的部署友好性主要在于以下几点:
无论好坏,相当多使用 TEE 的用例目前很难找到替代方案。我们相信 TEE 的引入进一步扩展了链上应用程序的开发空间,这可能推动新应用场景的产生。
在 TEE 中运行的程序仍然容易受到一系列攻击和错误的影响。就像智能合约一样,它们容易遇到一系列问题。为简单起见,我们将可能的漏洞分类如下:
无论是有意还是无意,开发人员都可以通过有意或无意的代码来削弱 TEE 中程序的安全保证。这包括:
开发人员再谨慎也可能成为运行时漏洞的牺牲品。开发人员必须仔细考虑以下任何一项是否会影响其项目的安全保证:
TEE 应用程序所使用的技术栈应该谨慎。在构建 TEE 应用程序时,可能出现以下问题:
最后但并非最不重要的一点是,关于如何真正运行一台执行 TEE 程序的服务器,也有一些实际注意事项:
我们将我们的建议分为以下几点:
1. 最安全的方案:无外部依赖项
创建高度安全的应用程序可能涉及消除外部依赖项,如外部输入、API 或服务,从而减少攻击面。此方法可确保应用程序以独立方式运行,没有可能损害其完整性或安全性的外部交互。虽然此策略可能会限制程序的功能多样性,但它可以提供极高的安全性。
如果模型在本地运行,则对于大部分 CryptoxAI 用例,可以实现此级别的安全性。
2. 采取的必要预防措施
无论应用程序是否具有外部依赖项,以下内容都是必须的!
将 TEE 应用程序视为智能合约,而不是后端应用程序;保持较低的更新频率,严格测试。
构建 TEE 程序应与编写、测试和更新智能合约时一样严格。与智能合约一样,TEE 在高度敏感且不可篡改的环境中运行,其中错误或意外行为可能导致严重后果,包括资金完全损失。彻底的审计、广泛的测试以及最少的、经过仔细审计的更新对于确保基于 TEE 的应用程序的完整性和可靠性至关重要。
审计代码并检查构建管道
应用程序的安全性不仅取决于代码本身,还取决于构建过程中使用的工具。安全的构建管道对于防止漏洞至关重要。TEE 仅保证提供的代码将按预期的流程运行,但无法修复构建过程中引入的缺陷。
为了降低风险,必须对代码进行严格的测试和审计,以消除错误并防止不必要的信息泄露。此外,可重复构建起着至关重要的作用,尤其是当代码由一方开发并由另一方使用时。可重复构建允许任何人验证 TEE 内执行的程序是否与原始源代码匹配,从而确保透明度和信任度。如果没有可重复构建,确定 TEE 内执行程序的确切内容是几乎是不可能的,从而危及应用程序的安全。
例如,DeepWorm(在 TEE 中运行蠕虫大脑模拟模型的项目)的源代码是完全开放的。TEE 内的执行程序是使用 Nix 管道以可重现方式构建的。
使用经过审计或验证的库
在 TEE 程序中处理敏感数据时,请仅使用经过审计的库进行密钥管理和私有数据处理。未经审计的库可能会暴露密钥并损害应用程序的安全性。优先考虑经过充分审查、以安全为中心的依赖项,以维护数据的机密性和完整性。
始终验证来自 TEE 的证明
与 TEE 交互的用户必须验证 TEE 产生的远程证明或验证机制,以确保安全可信的交互。如果没有这些检查,服务器可能会操纵响应,从而无法区分真实的 TEE 输出和被篡改的数据。远程证明为在 TEE 中运行的代码库和配置提供了关键证明,我们可以基于远程证明判断 TEE 内执行的程序是否与预期一致。
具体的鉴证可以在链上(IntelSGX、AWSNitro)、使用 ZK 证明(IntelSGX、AWSNitro)在链下验证,也可以由用户自己或托管服务(如 t16z 或 MarlinHub)进行验证。
3. 依赖于用例的建议
根据应用程序的目标用例及其结构,以下提示可能有助于使您的应用程序更安全。
确保始终在安全通道执行用户与 TEE 的交互
TEE 所在的服务器本质上不受信任。服务器可以拦截和修改通信。在某些情况下,服务器读取数据但不更改数据可能是可以接受的,而在其他情况下,即使读取数据也可能是不可取的。为了降低这些风险,在用户和 TEE 之间建立安全的端到端加密通道至关重要。至少,请确保消息包含签名以验证其真实性和来源。此外,用户需要始终检查 TEE 给出远程证明来验证自己是否正在与正确的 TEE 通信。这确保了通信的完整性和机密性。
例如,Oyster 能够通过使用 CAA 记录和 RFC8657 来支持安全的 TLS 颁发。此外,它还提供了一个名为 Scallop 的 TEE 原生 TLS 协议,该协议不依赖于 WebPKI。
知道 TEE 内存是瞬态的
TEE 内存是瞬态的,这意味着当 TEE 关闭时,其内容(包括加密密钥)会丢失。如果没有一个安全的机制来保存这些信息,关键数据可能会永久无法访问,从而可能使资金或运营陷入困境。
具有 IPFS 等去中心化存储系统的多方计算(MPC)网络可以用作此问题的解决方案。MPC 网络将密钥拆分到多个节点,确保没有单个节点持有完整密钥,同时允许网络在需要时重建密钥。使用此密钥加密的数据可以安全地存储在 IPFS 上。
如果需要,MPC 网络可以向运行相同映像的新 TEE 服务器提供密钥,前提是满足特定条件。这种方法可确保弹性和强大的安全性,即使在不受信任的环境中也能保持数据的可访问性和机密性。
还有另一种解决方案,即 TEE 将相关交易分别交给不同的 MPC 服务器,MPC 服务器签名后进行聚合签名并将交易最终上链。这种方法的灵活性要低得多,不能用于保存 API 密钥、密码或任意数据(没有受信任的第三方存储服务)。
减少攻击面
对于安全关键型使用案例,值得以牺牲开发人员体验为代价尝试尽可能多地减少外围依赖。例如,Dstack 附带了一个基于 Yocto 的最小内核,其中仅包含 Dstack 工作所需的模块。甚至可能值得使用像 SGX(超过 TDX)这样的旧技术,因为该技术不需要引导加载程序或操作系统成为 TEE 的一部分。
物理隔离
通过将 TEE 与可能的人类干预进行物理隔离,可以进一步增强 TEE 的安全性。虽然我们可以通过将 TEE 服务器托管在数据中心和云提供商,相信数据中心可以提供物理安全。但像 Spacecoin 这样的项目正在探索一个相当有趣的替代方案——太空。SpaceTEE 的论文依靠安全措施,例如测量发射后的惯性矩,以验证卫星在进入轨道的过程是否偏离预期。
多重证明者
正如以太坊依赖多个客户端实现来降低影响整个网络的 bug 风险一样,multiprovers 使用不同的 TEE 实现方案来提高安全性和弹性。通过跨多种 TEE 平台运行相同的计算步骤,多重验证可确保某一个 TEE 实现中的漏洞不会危及整个应用程序。虽然这种方法要求计算流程是确定性的,或者在非确定性情况下定义不同 TEE 实现方案间的共识,但它也提供了故障隔离、冗余和交叉验证等显著优势,使其成为需要可靠性保证的应用程序的不错选择。
TEE 显然已成为一个非常令人兴奋的领域。如前所述,AI 的无处不在及其对用户敏感数据的持续访问意味着 Apple 和 NVIDIA 等大型科技公司正在其产品中使用 TEE,并将 TEE 作为其产品的一部分提供。
另一方面,加密社区一直非常注重安全。随着开发人员尝试扩展链上应用程序和用例,我们已经看到 TEE 作为一种在功能和信任假设之间提供正确权衡的解决方案而变得流行。虽然 TEE 不像完整的 ZK 解决方案那样信任最小化,但我们预计 TEE 将成为首次慢慢融合 Web3 公司和大型科技公司产品的途径。
【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。