4、固件加密与签名:对称/非对称加密算法选择、数字签名流程、固件完整性校验、抗重放攻击设计

各位同行,咱们接着聊OTA安全。前面几章我们把传输通道和云端防护聊透了,今天要啃的这块骨头,是OTA安全里最核心、也最容易出纰漏的环节——固件加密与签名。

说白了,就是解决两个问题:固件会不会被偷看?固件会不会被篡改? 我在项目里见过太多人把这两件事混为一谈,结果出了大篓子。咱们今天就把它们掰开揉碎了讲清楚。

4.1 对称加密 vs 非对称加密:怎么选?

先聊加密。加密的目的是防止固件在传输或存储过程中被窃取。你想想看,如果固件里藏着ECU的核心标定数据,或者某个关键算法的实现,被人扒出来逆向,那损失可就大了。

加密算法分两类:对称加密和非对称加密。我个人的习惯是,在OTA场景下,两者结合使用,而不是二选一。

特性 对称加密 (AES) 非对称加密 (RSA/ECC)
密钥数量 1个密钥,加密解密用同一个 2个密钥,公钥加密私钥解密
计算速度 极快,适合大文件 慢,比AES慢100-1000倍
密钥分发 困难,需要安全通道传递密钥 容易,公钥可以公开
典型算法 AES-128/256, SM4 RSA-2048, ECC-P256, SM2
OTA适用场景 加密固件本体 加密对称密钥、数字签名

嗯,这里要注意:千万不要直接用非对称加密去加密整个固件。我曾经见过一个团队,用RSA加密一个100MB的固件包,结果ECU解密花了整整40分钟,车主直接投诉到售后了。非对称加密的计算开销太大,不适合大块数据。

我建议的做法是混合加密

  1. 生成一个随机的对称密钥(比如AES-256密钥)
  2. 用这个对称密钥加密固件本体
  3. 再用非对称加密(比如RSA公钥)加密这个对称密钥
  4. 把加密后的固件 + 加密后的密钥一起打包下发

这样既利用了对称加密的速度优势,又解决了密钥分发的难题。ECU收到包后,先用私钥解密出对称密钥,再用对称密钥解密固件。整个过程流畅且安全。

核心原则: 对称加密保速度,非对称加密保安全。两者结合,才是OTA加密的正道。

4.2 数字签名流程:给固件盖个章

加密解决的是「偷看」问题,但解决不了「篡改」问题。你想想看,如果攻击者截获了你的加密固件,虽然解不开,但他可以搞破坏——比如把加密后的数据块顺序调换,或者直接丢弃一部分。ECU解密后得到的是乱码,轻则升级失败,重则ECU变砖。

这时候就需要数字签名了。数字签名的作用是:证明这个固件确实来自合法的发布方,并且没有被篡改过

我在项目中遇到过一起事故:某Tier1供应商在开发阶段,为了调试方便,跳过了签名验证步骤。结果测试车在路试时,OTA升级包被测试工具误修改了一个字节,导致ECU刷写后无法启动。从那以后,我要求所有项目必须把签名验证做成「硬开关」——代码里写死,不允许通过配置关闭。

数字签名的标准流程是这样的:

  1. 哈希计算: 对固件内容做一次哈希运算(比如SHA-256),得到固定长度的摘要(digest)。
  2. 签名生成: 用发布方的私钥对摘要进行加密,生成数字签名。
  3. 打包下发: 将固件 + 数字签名 + 发布方证书一起打包,发送给车辆。
  4. 验签流程(ECU侧):
    • 用发布方公钥解密签名,得到原始摘要
    • 对收到的固件重新计算哈希,得到新摘要
    • 比较两个摘要是否一致

如果一致,说明固件是完整的、来源是可信的。如果不一致,直接拒绝升级。

避坑指南: 我曾经见过一个项目,签名时用的是SHA-1哈希算法。SHA-1已经被证明存在碰撞攻击风险,虽然实际利用难度高,但作为安全方案,我们不应该给自己埋雷。现在行业标准是SHA-256起步,国密方案用SM3。

4.3 固件完整性校验:不止是验签

数字签名其实已经包含了完整性校验的功能。但为什么我还要单独拿出来讲?因为在实际的OTA流程中,完整性校验需要分层、分阶段进行,不能只依赖最后那一次验签。

我个人习惯把完整性校验分成三个层次:

  • 传输层校验: 固件包在下载过程中,通过HTTPS的TLS层保证传输完整性。如果下载中断或数据包损坏,TCP/IP协议栈会触发重传。这是第一道防线。
  • 包级别校验: 固件包下载完成后,先做一次CRC32或MD5校验,确保整个包没有在存储过程中损坏。这一步很快,适合在ECU资源受限的情况下快速筛查。
  • 签名级别校验: 这是最终的金标准。用数字签名验证固件的完整性和来源可信性。只有这一步通过了,才允许进入刷写流程。

你可能会问:既然有签名校验了,为什么还要做前面的CRC?原因很简单——性能。签名验签涉及非对称加密运算,在低端MCU上可能需要几百毫秒甚至几秒。而CRC校验只需要几毫秒。如果固件在存储过程中因为Flash坏块导致损坏,CRC能快速发现并触发重下载,避免走到签名验证那一步才发现,白白浪费计算资源。

注意: 千万不要用CRC替代签名校验。CRC只能检测随机错误,无法防止恶意篡改。攻击者完全可以修改固件后重新计算CRC。完整性校验的最终防线,必须是基于非对称加密的数字签名。

4.4 抗重放攻击设计:别让旧固件钻了空子

重放攻击是什么?简单说,就是攻击者截获了一个合法的OTA升级包,然后在后续某个时间点,把这个旧包重新发送给车辆。如果车辆没有防护机制,就会接受这个旧固件,导致版本回退。

你想想看,如果攻击者截获了某个存在安全漏洞的旧版本固件,然后在你修复漏洞后,通过重放攻击让车辆回退到有漏洞的版本,那你的安全补丁就白打了。

我在项目中遇到过类似的情况:某OEM的OTA系统没有做抗重放设计,结果安全团队在测试时,成功用三个月前的旧固件包「降级」了一台测试车。虽然只是测试,但这件事让整个团队都惊出了一身冷汗。

抗重放攻击的常见方案有几种:

  • 版本号校验: 在固件包的元数据中嵌入版本号,ECU在升级前比较当前版本和目标版本。只允许升级,不允许降级。这是最基础、最有效的方案。
  • 时间戳+有效期: 在签名时加入时间戳,ECU验证签名时检查时间戳是否在有效期内。过期的固件包直接拒绝。这个方案需要ECU有可靠的时间源。
  • 随机数挑战: ECU在发起升级请求时生成一个随机数,云端在签名时把这个随机数包含进去。这样每个升级包都是独一无二的,无法被重放。

我个人最推荐的是版本号校验 + 时间戳的组合方案。版本号校验简单可靠,时间戳可以防止攻击者利用旧版本号但篡改时间戳。两者结合,基本可以堵死重放攻击的路径。

设计要点: 版本号必须包含在签名数据中,不能单独传输。否则攻击者可以修改版本号后重新打包。签名保护的是整个数据块,包括版本号、时间戳、固件哈希等所有关键信息。

好了,关于固件加密与签名,核心内容就是这些。总结一下我的建议:

  • 加密用混合方案,对称加密保速度,非对称加密保密钥安全
  • 签名用SHA-256 + RSA/ECC,私钥必须硬件安全存储
  • 完整性校验分层做,但最终防线必须是数字签名
  • 抗重放用版本号+时间戳,关键字段必须纳入签名保护

下一章我们聊聊升级过程中的安全监控与异常处理。嗯,那部分内容更贴近实战,到时候我会分享几个我亲手处理过的安全事件案例,保证让你有收获。