物联网边缘节点的安全启动与固件完整性,本质上是给每台设备装上“可信的出厂指纹”和“运行时的自我检查机制”,确保设备从通电第一行代码到长期运行,都只执行经过验证的固件,防止被植入后门或篡改。
为什么边缘节点比云端服务器更容易被“动手脚”
传统数据中心有物理门禁、监控摄像头、专人巡检,而物联网边缘节点往往部署在户外基站、工厂车间、路边机柜甚至无人值守的偏远区域,攻击者只需要一把螺丝刀、一个调试串口或者一张SD卡,就能物理接触设备。
物理接触意味着可以尝试固件提取焊下Flash芯片用编程器读取,或者通过UART串口进入bootloader,把整个文件系统导出来分析,更常见的攻击方式是固件替换:在设备断电间隙,把篡改过的固件写回存储芯片,让设备下次启动时加载恶意代码。
行业共识认为,边缘节点的安全启动机制,是抵御这类物理攻击的第一道闸门,它不是为了防黑客远程入侵,而是为了确保即使攻击者拿到了硬件,也无法让设备运行未经签名的代码。
安全启动的完整流程:从ROM代码到应用分区
信任根:芯片出厂时烧录的不可变密钥
每颗支持安全启动的处理器(比如NXP i.MX系列、STM32MP1、TI AM64x)内部都有一个Boot ROM,这段代码在芯片制造时固化,无法被修改,芯片出厂时会在一次性可编程存储器(eFuse)里烧录根公钥哈希或根证书。
这个eFuse区域很关键,它既能存储密钥,也能通过熔断的方式锁定调试接口,比如把JTAG端口烧断,外部调试器就无法再连接CPU内核,防止攻击者用调试工具旁路启动流程。
逐级验证:每一级引导代码都要签名
安全启动采用“链式信任”模型,上电后,Boot ROM加载第一级引导程序(通常是Bootloader的头部),先用eFuse里的公钥校验这段代码的签名,验证通过后,把控制权交给它,第一级引导程序再去加载第二级(比如U-Boot),同样做签名验证,U-Boot再验证内核镜像、设备树和initramfs。
这个过程像洋葱一样层层包裹,任何一级的代码如果被改动,签名校验就会失败,设备会进入恢复模式或者拒绝启动,关键点是

每一级都要独立的签名密钥,即使攻击者拿到内核密钥,也无法伪造Bootloader签名。
实测操作:在U-Boot中查看安全启动状态
以常见的使用U-Boot的ARM平台为例,在设备串口控制台执行:
setenv bootdelay 3
saveenv
如果设备启用了安全启动,sf probe之后执行sf read读取固件分区,再用fatload mmc 0 $loadaddr kernel.itb加载镜像,U-Boot会自动在加载时验证签名,可以输入help hab(NXP平台)查看HAB(High Assurance Boot)状态,返回HAB Configuration: secure表示安全启动生效,如果显示closed或者Open,说明配置未完成。
固件完整性:不只是启动时校验一次
很多设备在启动时通过了安全验证,但运行几周后,固件被运行时漏洞利用写入恶意代码,这部分修改绕过了启动链路,因为下次重启前并不会重新检查,所以运行时的固件完整性监控同样重要。
静态完整性度量:TPM PCR值与远程证明
现代边缘节点可以选配TPM 2.0安全芯片(或者使用芯片内置的TrustZone),启动过程中,每加载一个固件组件,就计算它的哈希值,并扩展(extend)到TPM的特定平台配置寄存器(PCR)里。
由于PCR值只能扩展不能回退,最终组合值就代表了设备当前运行固件的唯一指纹,远程管理平台可以用挑战-应答机制请求设备读取PCR值,并比对预期值,如果设备被刷入篡改固件,PCR值必然不同,远程平台就能识别并隔离该设备。
推荐在Linux系统下安装了tpm2-tools之后执行以下命令查看当前PCR摘要:
sudo tpm2_pcrread sha256:0
每个PCR值对应不同组件,比如PCR0通常代表BIOS/固件,PCR8代表内核扩展,记录基线值后,每次巡检比对。
动态完整性:IMA机制监控文件系统
光看PCR还不够,因为运行中的内核内存可能被修改,Linux内核提供了IMA(Integrity Measurement Architecture)框架,在内核配置中开启CONFIG_IMA后,可以做到:
-

在文件被访问时计算哈希,并与扩展属性(
security.ima)里保存的基准值比对 - 将度量结果记录在/var/log/ima目录中
- 与TPM联动,把每次文件验证的哈希扩展进PCR
启用IMA的典型做法是在内核启动参数里追加:
ima_policy=tcb ima_appraise_tcb
tcb策略会监控root用户访问的所有文件,生产环境建议用ima_policy=critical减少性能损耗,只监控关键二进制和配置文件。
实用对比:TPM与Boot ROM方案的差异
| 方案 | 验证时间点 | 是否需要单独芯片 | 防物理拆解能力 | 适合场景 |
|---|---|---|---|---|
| 片上Boot ROM验签 | 仅上电启动 | 否 | 强,密钥在eFuse | 成本敏感的小型节点 |
| TPM静态根信任 | 启动+运行时PCR扩展 | 是(或SoC集成) | 中,需配合总线加密 | 需要远程证明的工业网关 |
| 系统安全启动(UEFI Secure Boot) | 启动加载器与OS内核 | 可选 | 弱,仅验签 | x86平台边缘服务器 |
| 双备份+看门狗 | 连续运行 | 否 | 弱,防篡改能力一般 | 对恢复时间要求高的场景 |
开发实战:如何为边缘节点配置安全启动
生成密钥对并烧录eFuse
使用NXP CST工具或OpenSSL生成RSA-2048或ECC-256密钥对,公钥以CSF头格式嵌入Bootloader,烧录eFuse前务必确认熔断是一次性的,无法恢复,建议先在样板机上验证所有签名和烧录流程,再批量执行。
销毁密钥后要妥善保存私钥副本,最好存入硬件安全模块(HSM),由专人保管,私钥泄露等于安全启动形同虚设。
签名内核与设备树
以Yocto项目构建的系统为例,在local.conf中设置:
INHERIT += "signing-keys" IMAGE_KEY_DIR = "/path/to/key" UBOOT_SIGN_ENABLE = "1" KERNEL_SIGN_ENABLE = "1"
构建完成后,fitImage会包含签名节点,手动场景下可以用mkimage工具:

mkimage -f boot.its -k keys/ -r boot.itb
启用硬件加速验签
大部分平台支持硬件加密引擎,避免CPU软验签拖慢启动,例如NXP i.MX8的CAAM引擎,需要在设备树中配置fsl,sec-v4.0节点,并确保Boot ROM代码自动调用CAAM进行RSA验签,性能测试显示,基于硬件验签的启动时间通常比软件验签快2-4倍,对启动时间敏感的应用(如汽车ECU)至关重要。
断网环境下的固件更新:如何保证完整性
边缘节点经常处于弱网或断网环境,OTA升级不能依赖云端校验,推荐采用离线签名包+本地验签流程:
- 生产环境在隔离的签名服务器上生成固件包,附带签名值
- 更新包通过U盘或维护终端导入设备
- 设备端updater脚本调用
openssl dgst -sha256 -verify pubkey.pem -signature update.sig update.bin验证签名 - 验证通过后写入备用分区,并在下次启动时切换
这个流程能防止运维人员手中的U盘被植入恶意固件,也能防止下载到一半的文件损坏导致设备变砖。
常见问题与排查思路
安全启动失败时设备会有什么表现?
多数平台在验签失败后会进入恢复模式,串口打印类似Authenticate image fail或HAB Event错误日志,有些设备会反复重启,或者点亮红色LED,如果设备直接不能启动,优先检查eFuse是否被误熔断,尤其是SRK和JTAG锁定位。
为什么我关闭了安全启动,设备启动时间反而更短?
确实如此,验签需要额外的计算时间,一般在100-500毫秒之间,但对于运行在无人值守环境下的设备,这点时间换来的是防止被离线篡改的能力,完全值得,行业共识认为,对于暴露在公共区域的边缘节点,安全启动是必选项,而非可选项。
如何验证我的固件完整性方案是否有效?
可以做一个破坏性测试:用十六进制编辑器修改固件文件中某个字节,然后重新烧录,如果设备拒绝启动或者在IMA日志中记录到完整性错误,说明监控生效,建议在测试环境中固定安排这类演练,至少覆盖启动链的每一级。