硬汉嵌入式论坛

 找回密码
 立即注册
查看: 686|回复: 21
收起左侧

轻量级MCU中安全OTA漫谈

  [复制链接]

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
发表于 2026-1-24 23:22:09 | 显示全部楼层 |阅读模式
本帖最后由 会飞的猪_2020 于 2026-1-25 00:02 编辑

这篇文章记录了笔者对OTA升级的一些思考。我的目的是总结出OTA详细设计文档,喂给AI,让AI帮我实现一个OTA的代码。
在论坛里发表也是为了抛砖引玉和坛友们多多交流。
(AI创作声明,本文为笔者总结和AI之间的对话记录整理而成)

需求讨论——安全的OAT的“安全”一词具体体现在哪些方面?
1.运行可靠(必须)
这个是最基础的。至少升级不能升挂掉。如果升级过程中断电,需要保证至少能够回到BootLoader继续升级。

2.来源可靠(可选
确保固件是由可信任来源发布,而不是黑客伪造。

3.内容可靠(必须)
确保固件在弱网传输中没有因为网络干扰、丢包或者认为篡改而发生任何变动。

4.过程可靠(可选)
防止黑客通过监听OTA升级引脚逆向工程分析出你的固件,整个传输过程必须是加密的。

5.版本可靠(可选)
防止黑客通过回滚带有漏洞的合法固件,需要记录版本号。拒绝升级低版本固件

需求讨论——“轻量级”
6.轻量级(必须)
为嵌入式系统设计,功能需要通过宏定义可裁剪,最精简的版本仅保证运行可靠和内容可靠,保证较低的Flash的Ram占用,供用户选择。而对于安全性能需求高的,可以打开相关宏定义,以支持丰富的加密验证功能。

1.运行可靠如何满足?
1.1 单分区覆盖
针对Flash资源受限制的芯片,提供基础的BootLoader+单分区APP的方案,该方案需要在BootLoader中实现通讯协议,接受固件并采用覆盖擦除的方式升级。固件擦除过程中如果发生掉电会导致APP无法正常运行(可接受),但是要保证程序仍然处于BootLoader状态中,可以再次升级。

1.2 双槽位搬运
针对Flash资源足够的芯片,提供BootLoader+双分区APP的方案,该方案BootLoader中仅做固件搬运,不需要通讯协议。程序在分区1中运行,接收固件后写入分区2。最后在BootLoader中将分区2的固件转移到分区1中。该方案可以保证擦除过程中掉电,也可以回滚到上个版本继续运行。

1.3 双Bank切换
对于支持双Bank切换机制的单片机,可以使用硬件映射交换Bank1/2

2.来源可靠如何满足?
需要利用非对称加密的方案实现。(例如ECDSA)
非对称加密利用了陷门单向函数——一种正向计算容易,但是反向计算很困难数学函数。但是如果你知道“陷门”,这个反向计算过程,会从及其困难变为及其容易。

公钥:发布给公众,一个正向的,确定的数学计算。(任何人都可以在拥有公钥的情况下,对信息进行加密)
黑客:没有“陷门”,反向计算要好几亿年。哪怕黑客截获了通信的数据,也无法获得明文。
私钥:你偷偷知道的“陷门”,有了它,反向计算会变得特别容易。你就可以知道公钥加密的信息了。

因为非对称加密算法本身无法处理很大的数据(比如128KB的固件),如果试图去做,可能STM32要算好几分钟,这显然不可接受。
标准的做法:
a.先用SHA-256把128KB的固件浓缩成一个哈希值。
b.在用ECDSA对这个哈希值进行签名。

私钥 (Private Key):保存在你的开发服务器(上位机软件或云端),绝对不能泄露。
公钥 (Public Key):硬编码在 STM32 的固件中。


打包阶段(服务器):
对固件原始数据计算 SHA-256 哈希值。
使用 私钥 对哈希值进行加密,生成 签名 (Signature)。
将 固件 + 签名 + 版本号 组合成升级包。

接收阶段(STM32):
将下载到非运行 Bank 的固件通过 公钥 进行验签。
如果验签通过,说明:
固件确实是由持有私钥的人发布的(来源可靠)。
固件在传输过程中没有被篡改过(内容完整)。

[C] 纯文本查看 复制代码
openssl ecparam -name prime256v1 -genkey -noout -out private_key.pem

[C] 纯文本查看 复制代码
openssl ec -in private_key.pem -pubout -out public_key.pem
# 查看公钥的十六进制结构
openssl ec -in private_key.pem -pubout -outform DER | tail -c 64 | xxd -i



MCU中可以采用intel的tinycrypt库,进行加解密。

3.内容可靠如何满足?
每包采取CRC校验,错误重传。

4.过程可靠如何满足?
传输过程中采取AES对称加密。

5.版本可靠
通过业务逻辑加判断实现

本文中提到的密钥需要保存在读保护区域。并且默认黑客无法绕过MCU的读写保护。
如果假设存在一个万能的黑客,能够破解读写保护,那么上述的安全功能是无效的。
他可以直接修改固件,跳过if判断逻辑。


笔者目前生成了第一版的提示词,还没仔细给AI审核。先去睡觉了,明天晚上有空仔细改一下需求。
提示词放在了github上。
https://github.com/FlyyingPiggy2020/SMOTA
第一版提示词.7z (8.78 KB, 下载次数: 8)








评分

参与人数 4金币 +37 收起 理由
刘心武 + 20 很给力!
小梁呐 + 8 很给力!
casimir + 8 很给力!
摸鱼校尉 + 1 很给力!

查看全部评分

回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121126
QQ
发表于 2026-1-26 01:02:53 | 显示全部楼层
谢谢楼主分享。
回复

使用道具 举报

15

主题

165

回帖

210

积分

高级会员

积分
210
发表于 2026-1-26 09:21:26 | 显示全部楼层
还可以加版保芯片
回复

使用道具 举报

6

主题

21

回帖

39

积分

新手上路

积分
39
发表于 2026-1-26 10:19:29 | 显示全部楼层
可以考虑preboot-boot-app分区格式,其中preboot只做跳转,boot做升级app操作,app存放boot数组用于更新boot(可选)
回复

使用道具 举报

11

主题

737

回帖

770

积分

金牌会员

积分
770
发表于 2026-1-26 13:15:34 | 显示全部楼层
纯AI写出来的?牛。。。。。
回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
 楼主| 发表于 2026-1-26 15:18:58 | 显示全部楼层
hqgboy 发表于 2026-1-26 13:15
纯AI写出来的?牛。。。。。

没呢,还在编写提示词的阶段。
提示词写完了,尝试让AI干活。
回复

使用道具 举报

27

主题

285

回帖

366

积分

高级会员

积分
366
QQ
发表于 2026-1-26 15:37:40 | 显示全部楼层
没戳,我也是这样让 ai 干活的,让他自己先产出设计文档,然后严格按照设计文档实现就好了。

要不然写着写着 ai 容易左右脑互搏。
回复

使用道具 举报

27

主题

285

回帖

366

积分

高级会员

积分
366
QQ
发表于 2026-1-26 15:41:44 | 显示全部楼层
你这个一开始就搞得好宏大。

https://wiki.yono233.cn/YoroMCU-OTA/zh_hans/index.html

我这个当时也是让 ai 做的,但是只有最基础的功能。这都快半年了我还没有把周边工具都完善掉,更别提后续的安全加密、差分、备份回滚这些杂七杂八的东西。
回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
 楼主| 发表于 2026-1-26 15:59:43 | 显示全部楼层
今天继续细化一下细节。
因为第一版的提示词很多地方还没细化,要继续问AI争取把每个步骤分细一点,再让它去干活。

聊聊第四点过程可靠的具体实现
1.流式OR非流式
关于第四点,过程可靠。我需要一种加密方法,支持流式解密。
非流式:把加密后的固件,放到RAM里面,接收完毕在解密得到明文烧录到Flash。
流式:接收一包数据后,解析成明文,烧录到Flash。然后一包包接收、解密完所有的报文。
显然非流式是不合理的,因为嵌入式设备不一定有那么大的RAM可以保存整个固件,流式的方式更加适合嵌入式。

2.对称OR非对称
非对称更安全,但是速度慢,可加密数据段。不适合作为固件的加密方式。
对称加解密用同一个密钥,速度快(1~5ms),支持任意长度。

3.对称密钥如何分发
一机一密。如果某台设备的密钥被破解,不至于导致所有设备的密钥被破解。但是因为是对称式加密,所以如何分发密钥呢?
1.产线预注入
生产情况下随机产生密钥,将密钥和UID建立数据库放入服务器。优点是纯粹随机生成,不可能破解。缺点是数据库丢失,无法OTA。
2.基于UID派生
生一个随机的Master Key,混淆存储在BootLoader源码中,服务器也保存这个MasterKey。
UID明文上报,根据UID,利用不可逆的计算方法,计算出一个密钥。
例如:Device_AES_Key = HMAC-SHA256(Master_Key, UID)
然后保护好Master Key,就可以保证安全。
(本文讨论情况中,黑客无法破解芯片的读写保护,否则一切都是徒劳)











回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
 楼主| 发表于 2026-1-26 20:50:45 | 显示全部楼层
1.继续细化了部分文档,单独输出到doc文件夹内。
2.搭建了windows上用于纯逻辑验证的编译环境。
3.制定了smota_config.h,完成了宏定义的设计。
4.实现了生成密钥的python脚本
回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
 楼主| 发表于 2026-1-26 20:54:39 | 显示全部楼层
PKB404 发表于 2026-1-26 09:21
还可以加版保芯片

计划让用户自行提供获取密钥的函数,这样子可以自行混淆或者通过安全芯片读取密钥了[设计文档]。
回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
 楼主| 发表于 2026-1-27 08:42:57 | 显示全部楼层
勘误:"2.来源可靠如何满足?"中的内容说反了。
这里应该是指数字签名,它的逻辑和加密通讯正好相反。
公钥:发布给公众,一个正向的,确定的数学计算。(任何人都可以在拥有公钥的情况下,对信息进行加密)
黑客:没有“陷门”,反向计算要好几亿年。哪怕黑客截获了通信的数据,也无法获得明文。
私钥:你偷偷知道的“陷门”,有了它,反向计算会变得特别容易。你就可以知道公钥加密的信息了。

上述的描述写反了。

用私钥加密信息,公钥用于验证这个信息是否为配对的私钥生成。
所以说私钥就像一个数字签名,就只有你拥有,别人哪怕知道公钥,只能证明这个消息是你颁布的。
回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
 楼主| 发表于 2026-1-27 12:47:42 | 显示全部楼层
目前在设计协议阶段遇到了点问题。感觉给我生成的内容,不符合我的要求。每次让他微调,他都无法保证上一次交流的部分不变。
比如我要改A,它在改了A的同时,偷偷摸摸有微调了C和D。。

我这部分目前在用古法写文档。自己手敲的方式实现。实现大概框架之后,再让AI帮我润色。
回复

使用道具 举报

2

主题

70

回帖

76

积分

初级会员

积分
76
发表于 2026-1-28 15:53:09 | 显示全部楼层
可以的,期待更新
回复

使用道具 举报

30

主题

426

回帖

516

积分

金牌会员

积分
516
发表于 2026-1-28 15:57:30 | 显示全部楼层
我觉得一次性做的工作太多了,AI把持不住或者是人引导AI的手法还不是很熟练,像加密、固件签名功能是可裁剪的,应该单独开发,先不要放进去,先把基本功能做了。
你可以参考一下mcuboot,和你的想法很多相似的
回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
 楼主| 发表于 2026-1-30 16:32:22 | 显示全部楼层
本帖最后由 会飞的猪_2020 于 2026-1-30 16:34 编辑
tovinz 发表于 2026-1-28 15:57
我觉得一次性做的工作太多了,AI把持不住或者是人引导AI的手法还不是很熟练,像加密、固件签名功能是可裁剪 ...
SMOTA_20250130_未完成.7z (1.39 MB, 下载次数: 1)

花了一番功夫写文档,然后上班的时候一边工作,一边让AI帮我写这个项目。
目前在windows的模拟环境下编译通过了。告诉他利用build.sh可以进行编译。然后AI自己修改的。
(仅仅编译通过,没有检查对不对)

感觉要想办法搞个测试的方法,不过我不会写上位机。目前还在探究。

如果有验证的测试用例可以闭环的话,我感觉AI真能自己干活。
只不过我们嵌入式想 离开硬件 搞闭环,还是比较麻烦的。
回复

使用道具 举报

30

主题

426

回帖

516

积分

金牌会员

积分
516
发表于 2026-1-30 16:34:37 | 显示全部楼层
会飞的猪_2020 发表于 2026-1-30 16:32
花了一番功夫写文档,然后上班的时候一边工作,一边让AI帮我写这个项目。
目前在windows的模拟环境下编 ...

试一下 kiro 的 spec 工作模式,先编写 task 计划
Kiro: Agentic AI development from prototype to production
回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
 楼主| 发表于 2026-1-30 16:42:25 | 显示全部楼层
tovinz 发表于 2026-1-30 16:34
试一下 kiro 的 spec 工作模式,先编写 task 计划
Kiro: Agentic AI development from prototype to pro ...

最近看李总搞了一个vscode插件。
https://github.com/pikasTech/MDTODO
可以根据TODOLIST,一步步操作。

能开几十个Claude Code一起并行干活。不知道是不是一样的东西
回复

使用道具 举报

30

主题

426

回帖

516

积分

金牌会员

积分
516
发表于 2026-1-30 16:45:08 | 显示全部楼层
会飞的猪_2020 发表于 2026-1-30 16:42
最近看李总搞了一个vscode插件。
https://github.com/pikasTech/MDTODO
可以根据TODOLIST,一步步操作 ...

ScreenShot_2026-01-30_164523_214.png
回复

使用道具 举报

22

主题

122

回帖

188

积分

初级会员

积分
188
发表于 2026-1-30 18:30:24 | 显示全部楼层
本帖最后由 刘心武 于 2026-1-30 19:42 编辑

AI 输出设计文档后,编译环境、搭建整个工程如何搞得?也是 AI 一站式输出吗?有没有教程,对于这个心动了。是用 Claude Code 搞的吗?
回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
 楼主| 发表于 2026-1-31 10:21:12 | 显示全部楼层
本帖最后由 会飞的猪_2020 于 2026-1-31 10:45 编辑
刘心武 发表于 2026-1-30 18:30
AI 输出设计文档后,编译环境、搭建整个工程如何搞得?也是 AI 一站式输出吗?有没有教程,对于这个心动了 ...

录了两个视频但是麦炸了..懒得重录了。
第一个视频,是在家里的电脑重新安装开发环境,折腾了三十分钟,没想到这么曲折。
第二个视频,是简单演示了一下怎么用。

24小时内有效
回复

使用道具 举报

22

主题

122

回帖

188

积分

初级会员

积分
188
发表于 2026-1-31 11:00:45 | 显示全部楼层
会飞的猪_2020 发表于 2026-1-31 10:21
录了两个视频但是麦炸了..懒得重录了。
第一个视频,是在家里的电脑重新安装开发环境,折腾了三十分钟, ...

感谢感谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-2-24 13:45 , Processed in 0.071365 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表