当前位置: 首页 > news >正文

Sealing Enclave相关知识点, 来自kimi

Enclave 详细介绍下

一、什么是 Enclave
Enclave 是 Intel SGX(Software Guard Extensions)技术里的一段 受 CPU 硬件保护的执行区域。
  • 位于 用户态进程地址空间 内;
  • CPU 加解密 所有内存页,外部 OS/VMM/Root 无法窥探或篡改;
  • 代码/数据仅在 进入 Enclave 后 才解密并明文可见,退出时立即 “擦除”。
二、生命周期总览
 
┌── 应用进程 ──────────────────────────────┐
│  ┌──────────────────────────┐           │
│  │  普通区(Untrusted)      │           │
│  │  sgx_create_enclave()    │──┐        │
│  └──────────────────────────┘  │        │
│                                ▼        │
│  ┌──────────────────────────┐           │
│  │  ECREATE                 │  EINIT    │
│  │  EADD/EEXTEND           │◄─┘         │
│  │  EINIT → 运行态 Enclave │           │
│  └──────────────────────────┘           │
│        ▲      │                         │
│        │      └─EEXIT/ERESUME           │
└────────┴────────────────────────────────┘
 
  1. 构建阶段:sgx_sign 生成 SIGSTRUCT,计算 MRENCLAVE/MRSIGNER。
  2. 加载阶段:ECREATE→EADD→EEXTEND→EINIT 把 ELF 段映射到 EPC(Enclave Page Cache)。
  3. 运行阶段:通过 EENTER 进入,AEX 退出;支持 异步抢占(EDMM)。
  4. 销毁阶段:进程退出或 sgx_destroy_enclave 即自动擦除 EPC。
三、硬件与软件组件
层级组件作用
CPU 指令 ECREATE, EADD, EINIT, EENTER, EEXIT, EGETKEY, EREPORT 创建/进入/退出/派生密钥/生成报告
内存 EPC(Enclave Page Cache) 物理 RAM 中加密缓存,大小由 BIOS 配置
驱动 Intel SGX Driver 用户态与 EPC 的桥梁,暴露 /dev/sgx_*
用户库 libsgx_urts.so(uRTS) 进程内管理 Enclave 生命周期
可信库 libsgx_trts.a(tRTS) Enclave 内 C/C++ 运行时、异常、线程
AESM 服务 Application Enclave Service Manager 提供 EPID/DCAP 证明、密钥配置
四、常用 API 速查
功能API典型用法
创建 sgx_create_enclave() 返回 sgx_enclave_id_t
进入 sgx_ecall(enclave_id, func_id, ...) 触发 EENTER
退出 Enclave 内 ocall → sgx_ocall() 触发 EEXIT
密钥 sgx_get_key(&key_request, &key) 派生 Sealing/Report Key
证明 sgx_create_report() → sgx_verify_report() 本地证明
远程证明 sgx_ra_get_msg1/3() EPID/DCAP 远程证明
五、内存模型
  • ELRANGE:Enclave 线性地址空间(32/64 位均可配置)。
  • SSA(State Save Area):保存被中断时的寄存器,用于 AEX。
  • TCS(Thread Control Structure):每线程一个,管理进入/退出状态。
六、安全边界
  • 机密性:EPC 页 AES-128 加密,密钥仅存 CPU 内部。
  • 完整性:每页带 MAC,篡改即触发 #PF → SIGBUS。
  • 重放保护:单调计数器(sgx_create_monotonic_counter)。
  • 侧信道:需做恒定时间实现、ORAM、数据盲化等高层防护。
七、典型应用
  • 密钥保管:HSM 替代、密码库、数据库主密钥。
  • 隐私计算:联邦学习、隐私数据清洗。
  • DRM/许可证:加密内容密钥、许可证验证。
  • 区块链:TEE-based Oracle、跨链桥私钥托管。
八、限制与注意
  • EPC 大小有限(典型 64 MB-1 GB)。
  • I/O 必须 OCall 到 untrusted 代码。
  • 调试版 Enclave(SIGSTRUCT.DEBUG=1)可被 GDB 窥探;生产需关闭。
  • 侧信道攻击(L1TF、Foreshadow、Plundervolt)需补丁 + 编译器缓解。
九、一句话总结
Enclave 是 CPU 级保险箱:把敏感代码和数据塞进一个 硬件加密的孤岛 里运行,外部世界只能看见黑盒输入输出,其余全部“不可见、不可改”。

 

Sealing Enclave:概念、原理与落地细节

一、为什么会出现 Sealing Enclave

  • Enclave 生命周期短暂
    Enclave 在进程退出或系统关机时会被销毁,所有内存数据随之消失。
  • 数据要持久化
    如果以后还要用这些数据(密钥、模型、状态等),就必须在 Enclave 外部(磁盘、数据库、网络)保存。
  • 外面不可信
    所以数据 必须先加密、完整性保护,再离开 TEE 边界。
  • Sealing 就是 Intel SGX 提供的 “把 Enclave 内部机密打包成可外存 blob” 机制。

二、Sealing 核心流程(两步走)

步骤操作关键 API说明
Seal Enclave → 加密数据 → 生成 blob sgx_seal_data

使用 Sealing Key 对明文进行 AES-GCM 或自定义算法加密,附加 MAC 和元数据
Unseal blob → 解密 → 还原明文 sgx_unseal_data 只有 相同或更高安全版本的 Enclave 才能重新算出 Sealing Key,完成解密

三、Sealing Key 的两种派生策略

策略派生依据适用场景迁移能力
MRENCLAVE Enclave 度量值 单个 Enclave 专属 ❌ 不能升级、不能迁移
MRSIGNER 签名者公钥 + SVN 同一签名者发布的所有版本 ✅ 支持版本升级、跨 Enclave 共享
  • SVN(Security Version Number) 防止旧版本 Enclave 读取新版本密封的数据。
    只有 当前 SVN ≥ 密封时的 SVN 才允许解封。

四、Sealing Enclave 的典型工程结构

一个最小可运行示例通常包含:
App/                 # 非可信应用├─ App.cpp          # 调用 sgx_create_enclave、seal/unseal
Enclave_Seal/        # 密封专用 Enclave├─ Enclave_Seal.cpp # 实现 seal_ecall
Enclave_Unseal/      # 解封专用 Enclave├─ Enclave_Unseal.cpp # 实现 unseal_ecall
 
  • App 负责把密封后的 blob 写入文件。
  • Enclave_Seal / Enclave_Unseal 分别持有 sgx_seal_datasgx_unseal_data 的 ECall。
  • 通过 MRSIGNER+SVN 策略,两个 Enclave 即使不同版本也能共享数据 。

五、代码片段(C/C++)

cpp
// 在 Enclave 内 sgx_status_t seal(const uint8_t* plaintext, uint32_t len,uint8_t* sealed_blob, uint32_t* blob_len) {return sgx_seal_data_ex(SGX_KEYPOLICY_MRSIGNER, // 使用 MRSIGNER 策略0, // attribute_mask1, // SVN = 10, NULL, // additional_MACtextlen, plaintext,*blob_len, (sgx_sealed_data_t*)sealed_blob); }
 

六、Sealing vs. Remote Attestation

维度SealingRemote Attestation
目的 数据持久化 证明 Enclave 可信
密钥 Sealing Key(本地) Report Key / Provisioning Key
输出 sealed blob Quote / Report
使用场景 本地重启后继续用 远程服务器验证 Enclave

七、常见坑 & 最佳实践

  1. 策略选错
    用 MRENCLAVE 导致升级后无法读取旧 blob → 生产环境推荐 MRSIGNER + SVN。
  2. SVN 不递增
    更新 Enclave 后忘记加 SGX_MISCSELECT_SVN 会出现旧数据无法解封。
  3. 密钥轮换
    定期升级 SVN 并重新密封数据,防止旧版本被回滚利用。
  4. 容器场景
    把 sealed blob 放到 持久卷;容器销毁后重新拉起仍能解封。

八、一句话总结

Sealing Enclave = “把 Enclave 的机密数据,用只有它自己能解出来的密钥,加密后丢到磁盘上”,
解决了 TEE 数据生命周期短 与 持久化安全存储 之间的矛盾

 

Enclave的密钥存放在什么地方

一句话总结:
Enclave 的密钥“只活在 CPU 的加密寄存器和 EPC 内存里”——运行时由 SGX 指令现场派生并从不落盘;一旦断电或 Enclave 退出,密钥即消失。下表把“钥匙到底放哪儿”拆成三类典型场景说明:

场景密钥实际存放位置生命周期备注
运行时密钥 EPC 页 + 专属寄存器(RAX, RBX, …)

随 Enclave 创建→退出 永不离开 CPU 加密边界
Sealing 密钥 不存放;每次启动时由 EGETKEY 根据 MRENCLAVE / MRSIGNER + SVN 重新计算 与 Enclave 同生同灭 用于把机密“密封”成磁盘 blob,blob 可外存
持久化密钥 磁盘上只有密封后的 blob(文件 / DB / 云盘) 随文件持久化 重新启动后由 Sealing Key 解封回 EPC
因此:
  • 没有“文件路径”——密钥只在 EPC 加密内存 和 CPU 寄存器 里。
  • 断电即失——下次运行再派生,Sealing blob 是唯一可长期保存的“保险箱”。
 

Enclave 度量值是怎么算出来的

Enclave 的 度量值(MRENCLAVE) 是 32 字节 SHA-256 的累积哈希,计算过程由 CPU 微指令 在 构建阶段 完成,任何字节顺序、属性或布局的篡改都会改变该值。整个流程可以概括为 “三段式”:

1️⃣ ECREATE:初始化哈希上下文

  • 指令:ECREATE
  • 输入:SECS 结构体字段

    OffsetSize内容
    0 8 "ECREATE\0"
    8 8 SSAFRAMESIZE
    16 8 SIZE
    24 8 0(预留)
  • CPU 把 64 字节块喂给 SHA-256 初始状态,得到 MRENCLAVE 中间值。

2️⃣ EADD/EEXTEND:逐页累积

  • EADD(加载每一页)
    输入:页偏移、SECINFO(48 字节权限/类型)等 64 字节块,继续 SHA-256 扩展。
  • EEXTEND(可选,细粒度校验)
    把 256 字节页内数据再切成 4×64 字节块继续扩展,防止页内被篡改
⚠️ 地址使用 相对于 ELRANGE 起始的偏移,保证 可重定位(不因加载基址不同而改变度量值)。

3️⃣ EINIT:最终定值

  • 指令:EINIT
  • 动作:把 SIGSTRUCT 中的 Enclave-signer 数据再喂一次哈希,完成 SHA-256 最终化。
  • 结果:32 字节 最终 MRENCLAVE 写入 SECS.MRENCLAVE,之后任何修改都会被 CPU 拒绝。

✅ 一句话总结

Enclave 度量值是 CPU 用 SHA-256 对“构建指令序列 + 所有代码/数据页”实时累积的指纹,存储在 SECS.MRENCLAVE,生成后不可变,供远程证明或密封密钥派生。

 

断电后,之前保存的sealing blob怎么解出来

断电后,Sealing blob(即 *.sealed 文件)仍然躺在磁盘里,只要再次启动一个“合法”的 Enclave,就能把里面的明文原样解出来。核心流程只有三步:

1️⃣ 重新启动 解封 Enclave

要点说明
Enclave 必须满足解封条件 <ul><li><li><li>
不需要任何持久化密钥文件 解封用的 Sealing Key 是运行时由 CPU 的 EGETKEY 指令 即时派生 的,断电后根本不存在,也不需要。

2️⃣ 读取 Sealing blob 到内存

c
FILE *fp = fopen("secret.sealed", "rb");
fseek(fp, 0, SEEK_END);
size_t sz = ftell(fp);
uint8_t *blob = malloc(sz);
fread(blob, 1, sz, fp);
fclose(fp);
 

3️⃣ 进入 Enclave 调用 sgx_unseal_data

c
sgx_status_t ret = sgx_unseal_data((sgx_sealed_data_t *)blob,   // 来自磁盘NULL, 0,                     // 附加 MACplaintext, &plain_len);      // 输出的明文
 
  • CPU 再次计算 Sealing Key → AES-GCM 解密 → 完整性校验通过 → 明文回到 EPC。
  • 若 MRENCLAVE 策略,则 度量值必须完全一致;若 MRSIGNER 策略,则允许升级版本,只要签名者不变、SVN 不低于原值即可。

✅ 一句话总结

断电后 Sealing blob 只是普通文件;系统重启时,只要再跑一个“合规”的 Enclave,就能让 CPU 重新算出同样的 Sealing Key,把文件里的数据原样解封。
 

如果Enclave不满足解封条件,该怎么办?

当 Enclave 不满足解封条件(sgx_unseal_data 返回非 0 且内部错误码提示 “policy mismatch” 或 “invalid key”)时,可以按以下维度快速定位并给出补救方案。

1️⃣ 常见失败原因与对应补救


失败场景典型错误码根因可执行补救
MRENCLAVE 不一致 SGX_ERROR_MAC_MISMATCH / policy mismatch 代码/数据/布局被改动 放弃 — 数据只能被原 Enclave 打开,无法再生成相同 MRENCLAVE
MRSIGNER 不一致 SGX_ERROR_MAC_MISMATCH 签名证书换了 放弃 — 除非找回旧证书
SVN 过低 SGX_ERROR_INVALID_CPUSVN / policy mismatch 新 Enclave ISVSVN < 密封时的 ISVSVN 升级 Enclave — 把 ISVSVN 提高到 ≥ 密封值,重新签名即可
属性掩码不匹配 SGX_ERROR_INVALID_ATTRIBUTE XFRM/MISCSELECT 不同 重新编译 — 把 Enclave 的 attribute mask 调成与密封时一致
CPU/平台更换 SGX_ERROR_INVALID_CPUSVN CPU 微码或平台序列号变化 无解 — 只能把 blob 在原平台先解封,再重新密封到新平台

2️⃣ 实战排查清单

bash
# 1. 确认密封策略
sgx_sealed_data_t *blob = ...;
uint16_t key_policy = blob->key_request.key_policy;
# key_policy & 0x0001 -> MRENCLAVE
# key_policy & 0x0002 -> MRSIGNER# 2. 对比当前 Enclave 信息
sgx_report_t report;
sgx_create_report(NULL, NULL, &report);
printf("MRENCLAVE  : "); hexdump(report.body.mr_enclave.m);
printf("MRSIGNER   : "); hexdump(report.body.mr_signer.m);
printf("ISVSVN     : %u\n", report.body.isv_svn);# 3. 如果 SVN 不足
# 在 Enclave.xml 里把
#   <ISVSVN>2</ISVSVN>
# 改成 ≥ 密封时的版本,重新签名即可。
 

3️⃣ 无法补救时的兜底方案

  • 在原平台/原 Enclave 先解封
    把数据解密到明文 → 做业务迁移 → 用新 Enclave 重新密封。
  • 使用 Remote Sealing
    借助 远程证明 把密钥送到云端可信服务,云端再发回 用新 Enclave 公钥 包裹的密钥,实现“跨平台迁移”。

4️⃣ 一句话总结

“解封失败 ≠ 数据丢失”
  • MRENCLAVE/MRSIGNER 变就无解,只能回原 Enclave 或放弃。
  • SVN/属性不匹配 只需把 Enclave 升级或回编 到兼容版本即可。
  • 实在无法兼容,就在原平台先解封、再迁移、再重新密封。

 

MRENCLAVE和MRSIGNER 有什么区别

维度MRENCLAVEMRSIGNER
中文名称 Enclave 身份度量值 签名者身份度量值
计算来源 Enclave 代码、数据、页面顺序、属性 的 SHA-256 累积哈希 签名者 RSA 公钥 的 SHA-256 哈希
唯一性 每个二进制都唯一,哪怕只改 1 字节也会变 同一签名者共用,所有用同一把私钥签出的 Enclave 都一样
作用场景 本地完整性校验、本地证明、MRENCLAVE-Sealing(仅限原二进制解封) 远程证明、MRSIGNER-Sealing(同作者多版本可共享密钥)
是否支持升级 ❌ 不支持 — 代码/数据一改就失效 ✅ 支持 — 只要签名者不变,可跨版本、跨二进制共享数据
典型用途 单实例敏感数据存储 产品线密钥共享、版本升级兼容
一句话记忆
MRENCLAVE 像“指纹”,MRSIGNER 像“户口本” ——前者认人,后者认家族。

 

MRENCLAVE 和 MRSIGNER 在存储敏感数据时哪个更安全?

结论先行
  • MRENCLAVE 更“安全” —— 它把钥匙锁死在 唯一二进制 里,任何改动都无法再打开旧数据,因此 抗篡改/回滚 能力最强。
  • MRSIGNER 更“灵活” —— 允许同一签名者下的 多版本共享 数据,但引入了 旧版本漏洞回滚 的风险;需要额外用 SVN(Security Version Number) 来限制旧版本访问。

1️⃣ 安全模型对比

维度MRENCLAVE(Enclave Identity)MRSIGNER(Sealing Identity)
密钥派生依据 代码+数据+布局的 SHA-256 签名者 RSA 公钥的 SHA-256
密钥唯一性 每个二进制唯一 同一签名者共用
升级后能否解封旧数据 ❌ 不能 ✅ 可以(受 SVN 限制)
漏洞回滚风险 无(旧版本直接失效) 存在(低 SVN 旧版本仍可能运行)
适用场景 密钥/凭证 一次性 存储 产品 跨版本 密钥共享
Intel 官方示例:
  • MRENCLAVE 适合保存“用户登录令牌”——一旦代码被修补,旧令牌作废,用户必须重新授权。
  • MRSIGNER 适合保存“数据库主密钥”——升级补丁后仍要能打开旧加密文件。

2️⃣ 如何缓解 MRSIGNER 的回滚风险

  • 强制 SVN 递增
    SIGSTRUCT 中把 ISVSVN 每发一次安全补丁就加 1;
    密封时把 min_isvsvn 设为当前 SVN;
    低版本 Enclave 因 EGETKEY 拒绝而无法解封高 SVN 数据
  • 结合单调计数器
    sgx_create_monotonic_counter 在密封 blob 里保存计数器版本,防止 离线回滚 攻击。

3️⃣ 一句话总结

追求绝对安全 → 选 MRENCLAVE
追求可升级、可迁移 → 选 MRSIGNER + 递增 SVN

 


http://www.sczhlp.com/news/7243/

相关文章:

  • 如何查看别人的个人主页
  • 第十届现代管理、教育与社会科学国际学术会议(MMET 2025)
  • 著名心型线画法
  • char数组打印
  • 语法糖
  • 国内仍然可用docker镜像源汇总,长期维护
  • MyEMS 开源能源管理系统:技术内核与三级监测体系中的应用价值
  • MyEMS 开源能源管理系统:革新能源管控模式的技术实践与生态构建
  • 实现流程可控的镜像下载和存储(三)
  • IPv6文档新前缀:3fff::/20的诞生与应用
  • 首届Alexa Prize SimBot挑战赛五强揭晓
  • 洛谷 P10578 [蓝桥杯 2024 国 A] 旋转九
  • kali启动ssh
  • gdb调试core中的map,vector之类的容器对象
  • http://www.wiow.net/
  • AutoCAD 助手常青藤 4.72:一键批量打印+图形表格全能插件
  • Gitee:中国开发者首选的本土化DevOps平台解析
  • Zabbix监控Doris数据库
  • 分布式理论 CAP + Base
  • 线程安全锁
  • kali换源阿里云
  • 在WSUS下部分客户机没有向WSUS服务器更新状态解决
  • 281、将赴吴兴登乐游原
  • Lingo 12.0 图文安装指南 | 工业工程与运筹优化必备软件
  • Java面向对象——5.多态
  • 找工作在哪里找比较可靠?这6大平台助你轻松找工作
  • Proxmox停用Ceph
  • Gitee DevOps:本土化研发效能提升的引擎级解决方案
  • 工匠精神/Qt同时推流和录制16路1080p/CPU占用不到1%/实时性好/极低资源占用/优化到极致
  • Markdown 格式