定义
Firmware Signature(固件签名)对 OTA 固件包进行数字签名,设备升级前校验签名,确保固件来源可信、未被篡改。常与 X.509 Certificate 配合使用。
签名流程
构建阶段对固件包计算哈希(如 SHA-256),使用私钥对哈希签名,将签名附加至固件包或单独存储。设备端预置公钥或证书,下载固件后重新计算哈希、验证签名,通过后方可写入存储并重启。采用非对称加密(如 RSA、ECDSA),私钥由构建系统保管,公钥预置设备,防止固件被伪造或篡改。
与 CI/CD 集成
在 CI/CD 流水线中,构建完成后自动执行签名步骤,私钥由密钥管理系统(如 HSM、Vault)托管,避免泄露。平台上传固件时可校验签名有效性,拒绝未签名或签名无效的包。设备端 Bootloader 或 OTA 客户端需实现签名校验逻辑,确保升级安全。
安全最佳实践
私钥严格隔离,仅构建环境可访问;定期轮换签名密钥,设备需支持多证书验证;对 Full Package 与 Delta Package 均需签名;考虑供应链安全,防止产线固件被替换。固件签名是 FOTA 安全的基础保障,不可或缺。
签名证明的是包体来源
固件签名要回答的是两件事:这段字节是不是由持有私钥的构建过程产生,以及在传输和暂存期间有没有被改过。具体做法是对即将写入设备的内容计算哈希,用私钥对哈希签字,设备用预先置入的公钥或证书核验,通过之后才允许写入并切换启动。签名并不隐藏固件内容,需要保密时应另外加密,两者不能互相顶替。核验范围必须是设备实际写入的那一份字节。若只对压缩前的目录签字、设备却去核验解压后的镜像,或者只签了头部、包体仍可替换,核验就形同虚设。全量包和差分包各自都要有签名,差分所依据的基线版本也应放进被签名的材料,避免把补丁应用到错误的旧版本上。平台拒绝未签名的上传,只挡住了入口,替不了设备启动前的那一次核验。
设备上验签能够成立的前提
设备要能验签,必须在出厂或可信引导阶段就持有正确的公钥或证书链,并且这块信任根不能被待升级的固件自己悄悄换掉。若用证书有效期参与判断,设备时间严重偏离会把合法包拒绝掉,或把过期证书放进来,因此要规定时间不可信时怎么处理。私钥只能留在受控的签名环境,构建机上的普通账号不应能把它导出。轮换时,设备要能区分“旧密钥仍可核验已经发布的包、新密钥用于此后的包”,而不是一刀切作废,导致现场再也升不上去。引导程序若属于启动链的一环,它自己的更新也要纳入同一套信任,只签应用、不签引导,就留了绕过的口子。与空中升级任务配合时,平台登记的包哈希应与签名输入一致;A/B 分区切换之前,应再次确认即将启动的那一份已经核验过。
签的文件和下发的文件不是同一份
打包完成后又追加版本尾注,哈希已经变了却仍附上旧签名,是现场失败里很常见的一种。差分包拿全量包的签名去核,或拿解压后的内容去对压缩包的签名,都会失败,现象却像“包损坏”。测试密钥签出的包发到量产设备上,量产公钥无法通过,整批任务一起失败。为了方便刷机在量产设备上临时关掉验签,事后忘记打开,签名体系就等于不存在。证书主题没有和产品绑定,另一条产品线的合法包也能被本设备接受。只在平台上传时验签、设备端不验,下载链路或本地缓存仍可以换包。私钥随源码仓库里的脚本分发,签名就不再能证明来源。轮换之后只更新了平台、没有更新设备上的信任锚,新包会被全部拒绝。发布记录应按哈希找回当时的签名和密钥标识,事后才能核对某一次升级用的是哪一把。