一、HTTPS 还不够安全吗在上一篇文章中我们知道了 OTA 更新需要安全保护。你可能会想“现在网站都用 HTTPS 了OTA 直接用 HTTPS 不就行了吗”答案是不够。HTTPS 能做什么、不能做什么HTTPS 能保护HTTPS 不能保护数据传输加密防窃听服务器被攻破后下发的恶意更新防止中间人篡改数据服务器密钥被盗后的伪造签名验证服务器身份单点故障一个服务器被攻破就全完了一个真实的攻击场景攻击场景单一服务器被攻破 1. 黑客入侵了 OTA 服务器 2. 用服务器的合法证书签名了一个恶意固件 3. 所有设备通过 HTTPS 下载了这个合法的恶意固件 4. 设备验证签名✅ 通过确实是服务器的签名 5. 设备安装 系统被攻陷 HTTPS 的问题它只保护了传输过程 但不保护服务器本身被攻破的情况。这就是为什么 Uptane 设计了更复杂、更安全的机制。二、Uptane 的核心创新分离信任传统信任模型的问题传统模型单一信任点 ┌─────────────┐ │ 服务器 │ ◄── 被攻破 全完了 │ 唯一信任│ └──────┬──────┘ │ 所有设备都信任它Uptane 的分离信任模型Uptane 模型分离的信任责任 ┌─────────────────┐ ┌─────────────────┐ │ Image Repository│ │ Director │ │ (镜像仓库) │ │ (导演/控制器) │ │ │ │ │ │ 职责管理什么 │ │ 职责管理谁应该 │ │ 软件是合法的│ │ 获得什么 │ │ │ │ │ │ 密钥离线保管 │ │ 密钥在线使用 │ │ 长期 │ │ 短期 │ │ │ │ │ │ 签名软件包签名 │ │ 签名设备分配签名 │ └─────────────────┘ └─────────────────┘ │ │ └───────────┬───────────────┘ ▼ ┌─────────────┐ │ 设备 │ │ │ │ 验证逻辑 │ │ 1. 这个软件包 │ │ 在镜像仓库 │ │ 的列表里吗│ │ 2. 导演说我 │ │ 应该安装它吗│ │ 3. 两个签名 │ │ 都有效吗 │ │ │ │ 只有三个都 ✅ │ │ 才安装 │ └─────────────┘核心洞察即使 Director 被攻破黑客也只能让设备安装镜像仓库中已有的合法软件无法注入全新恶意软件。三、四种关键元数据文件Uptane 使用四种 JSON 格式的元数据文件来管理信任。让我们逐个了解1. root.json —— 信任的根作用定义整个系统的信任根包含所有角色的公钥。{signed:{_type:root,version:1,expires:2025-01-01T00:00:00Z,keys:{abc123...:{keytype:ed25519,keyval:{public:a1b2c3...}},def456...:{keytype:ed25519,keyval:{public:d4e5f6...}}},roles:{root:{keyids:[abc123...],threshold:1},targets:{keyids:[def456...],threshold:1},snapshot:{...},timestamp:{...}}},signatures:[...]}关键字段解释字段含义keys所有角色的公钥列表roles定义哪些密钥可以签名哪些元数据threshold阈值需要多少个签名才有效支持多签expires过期时间防止无限期使用旧密钥安全特性 根密钥离线保存极少使用 支持密钥轮换root.json 可以更新自己✍️ 多签支持需要 M-of-N 个签名2. targets.json —— 软件清单作用列出所有可用的软件包及其哈希值。{signed:{_type:targets,version:2,expires:2024-12-01T00:00:00Z,targets:{firmware_v1.2.3.bin:{length:1048576,hashes:{sha256:e3b0c44298fc1c149afbf4c8996fb924...},custom:{ecuIdentifier:ECU1,hardwareId:hw-model-a}},firmware_v1.2.4.bin:{length:1050000,hashes:{sha256:a1b2c3d4e5f6...}}}},signatures:[...]}关键字段解释字段含义targets软件包列表文件名 - 元数据length文件大小防止截断攻击hashes文件哈希验证完整性custom自定义字段ECU标识、硬件ID等两个 targets.json位置内容签名者Image Repository所有可用软件包镜像仓库 Targets 密钥Director特定设备的更新清单Director Targets 密钥3. snapshot.json —— 版本快照作用记录所有元数据的版本号防止回滚攻击。{signed:{_type:snapshot,version:5,expires:2024-06-15T00:00:00Z,meta:{targets.json:{version:2,length:2048,hashes:{sha256:f6e0a1b2c3...}},delegated_role1.json:{version:3,length:1024,hashes:{...}}}},signatures:[...]}为什么需要 snapshot攻击场景没有 snapshot 的回滚攻击 1. 新版本 v2.0 修复了一个安全漏洞 2. 黑客让设备下载旧版本的 targets.jsonv1.0 3. 设备安装了 v1.0有漏洞的版本 4. 攻击成功 有了 snapshot - 设备检查 snapshot.json 中的版本号 - 发现 targets.json 版本回退了 - 拒绝安装攻击失败4. timestamp.json —— 时间戳作用提供 freshness 保证防止无限期冻结攻击。{signed:{_type:timestamp,version:100,expires:2024-06-01T12:00:00Z,meta:{snapshot.json:{version:5,length:1024,hashes:{sha256:a1b2c3d4...}}}},signatures:[...]}特点⏰ 短期过期通常几小时到几天 频繁更新每次发布新版本都更新 轻量级只包含 snapshot 的哈希为什么需要 timestamp攻击场景冻结攻击 1. 黑客阻止设备获取新元数据 2. 设备一直使用旧的可能已经过期的元数据 3. 设备不知道有新版本可用 4. 设备永远停留在旧版本 有了 timestamp - 设备检查 timestamp.json 是否过期 - 如果过期且无法获取新的进入安全模式 - 防止被冻结在旧版本四、验证流程设备如何安全地安装更新完整的验证流程图设备收到更新指令后 ┌─────────────────────────────────────────┐ │ 1. 下载 timestamp.json │ │ ├── 检查签名Timestamp 密钥 │ │ ├── 检查是否过期 │ │ └── 记录 snapshot 版本号 │ └─────────────────┬───────────────────────┘ ▼ ┌─────────────────────────────────────────┐ │ 2. 下载 snapshot.json │ │ ├── 检查签名Snapshot 密钥 │ │ ├── 检查版本号 已知的版本 │ │ └── 记录所有元数据的版本和哈希 │ └─────────────────┬───────────────────────┘ ▼ ┌─────────────────────────────────────────┐ │ 3. 下载 Image Repository 的 targets.json │ │ ├── 检查签名Targets 密钥 │ │ ├── 检查版本号 已知的版本 │ │ └── 检查哈希与 snapshot 中一致 │ └─────────────────┬───────────────────────┘ ▼ ┌─────────────────────────────────────────┐ │ 4. 下载 Director 的 targets.json │ │ ├── 检查签名Director Targets 密钥 │ │ ├── 检查版本号 已知的版本 │ │ └── 检查所有目标文件都在 Image │ │ Repository 的 targets.json 中 │ └─────────────────┬───────────────────────┘ ▼ ┌─────────────────────────────────────────┐ │ 5. 下载目标文件固件 │ │ ├── 检查文件大小与 targets.json 一致 │ │ └── 检查文件哈希与 targets.json 一致 │ └─────────────────┬───────────────────────┘ ▼ ┌─────────────────────────────────────────┐ │ 6. 安装并上报 │ │ ├── 安装固件 │ │ ├── 生成安装报告manifest │ │ └── 上报给 Director │ └─────────────────────────────────────────┘关键安全点检查点防止的攻击签名验证伪造元数据攻击过期检查重放攻击、冻结攻击版本号检查回滚攻击哈希检查文件篡改攻击Image Director 交叉验证单点攻破攻击五、密钥管理安全的核心密钥层级结构┌─────────────────────────────────────┐ │ Level 1: Root 密钥 │ │ • 最顶层信任根 │ │ • 离线保存HSM/硬件安全模块 │ │ • 极少使用仅用于签名新的 root.json │ │ • 多签保护如 2-of-3 │ └─────────────────┬───────────────────┘ │ ┌─────────────────▼───────────────────┐ │ Level 2: Targets/Snapshot/Timestamp │ │ • 由 Root 密钥授权 │ │ • Targets 密钥通常离线 │ │ • Snapshot/Timestamp 密钥在线 │ └─────────────────┬───────────────────┘ │ ┌─────────────────▼───────────────────┐ │ Level 3: 委托密钥可选 │ │ • 可以委托给团队/供应商 │ │ • 例如让供应商签名自己的固件 │ └─────────────────────────────────────┘密钥安全实践密钥类型存储方式使用频率保护级别Root离线 HSM极少轮换时最高Targets离线或受保护每次发布软件高Snapshot在线服务器每次发布中Timestamp在线服务器频繁自动中Director在线服务器每次分配更新中六、动手实验查看真实的元数据实验 1查看 aktualizr 测试数据cd~/test/aktualizr# 查看测试用的元数据ls-latests/test_data/prov/metadata/# 查看 director 元数据ls-latests/test_data/prov/metadata/director/cattests/test_data/prov/metadata/director/root.json|python3-mjson.tool# 查看 repo 元数据ls-latests/test_data/prov/metadata/repo/cattests/test_data/prov/metadata/repo/root.json|python3-mjson.tool实验 2使用 uptane-generator 创建元数据cd~/test/aktualizr# 创建测试仓库mkdir-pmy-repo ./build/src/uptane_generator/uptane-generator generate\--path./my-repo\--keytypeED25519# 查看生成的结构ls-lamy-repo/ls-lamy-repo/repo/ls-lamy-repo/director/# 查看生成的 root.jsoncatmy-repo/repo/root.json|python3-mjson.tool实验 3添加一个软件包cd~/test/aktualizr# 创建一个测试固件echoThis is test firmware v1.0my-firmware.bin# 添加到仓库./build/src/uptane_generator/uptane-generator image\--path./my-repo\--filename./my-firmware.bin\--targetnamemy-firmware-v1.0# 查看 targets.json 的变化catmy-repo/repo/targets.json|python3-mjson.tool七、Uptane vs 其他安全机制对比表特性Uptane传统签名HTTPS传输安全✅❌✅服务器攻破防护✅❌❌回滚攻击防护✅❌❌冻结攻击防护✅❌❌密钥轮换✅⚠️❌多签支持✅⚠️❌离线根密钥✅⚠️❌复杂度高低低八、本章小结核心概念回顾概念一句话解释root.json信任的根定义所有角色的密钥targets.json软件清单列出所有可用软件包snapshot.json版本快照防止回滚攻击timestamp.json时间戳防止冻结攻击双仓库验证Image Repo Director双重确认密钥层级Root → Targets/Snapshot/Timestamp → 委托Uptane 的安全保证即使发生以下情况系统仍然安全 ✅ Director 服务器被攻破 → 只能让设备安装镜像仓库中已有的合法软件 ✅ Image Repository 的在线密钥被盗 → 根密钥离线保存可以轮换恢复 ✅ 网络被监听 → 所有通信加密元数据签名验证 ✅ 旧版本被重放 → snapshot.json 的版本号检查阻止回滚 ✅ 更新被拦截 → timestamp.json 过期检查触发警报下一步在下一篇文章《Primary 与 Secondary ECU——汽车里的更新主从架构》中我们将深入了解 ECU 的概念和分类理解 Primary 和 Secondary 的职责分工动手配置 aktualizr 的虚拟次 ECU观察主从 ECU 之间的通信过程九、延伸阅读与资源官方文档Uptane 标准: https://uptane.github.io/papers/ieee-isto-6100.1.0.0.uptane-standard.htmlTUF 规范: https://theupdateframework.io/推荐阅读《TUF: The Update Framework》论文《Securing Software Updates for Automobiles》论文思考题为什么 Uptane 需要四种元数据文件而不是一种如果 Director 被攻破攻击者能做什么、不能做什么设计一个场景假设你是攻击者如何尝试攻破 Uptane 系统然后思考 Uptane 如何防御本文作者姜焕铎目标读者有基础安全概念的开发者上一篇《OTA 更新是什么——从手机系统更新说起》下一篇《Primary 与 Secondary ECU——汽车里的更新主从架构》希望这篇文章让你理解了 Uptane 的核心安全机制。有任何问题欢迎在评论区留言讨论