• MCU固件加密


    起因

    大牛攻城狮最近遇到了一件伤心的事情,团队辛辛苦苦做板子,被别人拿去抄了,固件也被破了。想起那调代码的日日夜夜,多少辛苦都白费了,感觉这是个弱肉强食的时代,这里也要痛骂那些黑心老板,这样做对吗。只能暗暗怪自己当时图方便,没有把固件安全工作做好。

     这里把我使用工程贴出来,供大家参考,无积分免费下载,就是希望攻城狮早点用上这种方法,提升自身、行业价值。

    MCU固件加密,以STM32为例提供二级密钥方法,加密过程简单-嵌入式文档类资源-CSDN文库

    讨论

    好的加密

    我也搜了很多针对MCU固件加密的观点,总的来说,大家比较认可的方式是:

    1. 加密方式简单、占用MCU资源少
    2. 方便
    3. 破解成本高

    先说第一条,加密方法不能太复杂,MCU的计算能力和RAM/ROM资源有限,这是大家都认可的;

    其次是第二条,加密方法方便,只要加密多少都会带来一些不方便,软件人员最忌讳的就是不做任何加密手段,你发布的hex文件可以万能烧录,即害了自己、又害了老板、还拉低技术人员价值

    这里插一句题外话,针对方便,不同的角色有不同的理解。我这里完全站在软件攻城狮的角度来说方便。假如现在有量产1000套产品需要烧录,软件攻城狮如果可以自己烧录,那就好搞很多。但是往往现实中,软件攻城狮可能不是这家公司的人员或者不在那个城市,如果直接发hex文件,那怎么保证自己的利益呢?

    最后说破解成本,就是针对主流MCU的破解有个基本认识,现在的技术对于基于ID加密的方式还是比较容易破解的,破解成本也不高。

    常用加密

    常用的加密方法:

    第一:JTAG/SW关闭、设置FLASH不可以读。首先这类方法只是增加一点点破解成本,对于专业破解人员来说,这一步基本上没啥用,2千大洋基本可以读出你的hex文件。JTAG/SW关闭、设置FLASH不可以读,只是最初级的加密方式了。

    第二:读取ID,计算出来一个密钥key。根据这个密钥key判定ID是否注册,这种方式也比较容易破解了,可以通过修改获取的hex文件的代码中ID取值地址,这里就不细说,说多了都是泪啊!

    优化加密

    条件:已知一批芯片ID,软件攻城狮手上有个对应芯片的开发板或者工程板。

    步骤:

    1. 获取ID
    2. 计算一级密钥,一级密钥为芯片ID的累加和(也可以自定义一级密钥算法,这里为了简单说明采用累加和,一级密钥也不用太复杂,容易被破解)
    3. 代码中先填入芯片ID、一级密钥,编译下载到开发板上,运行获取二级密钥
    4. 将二级密钥填写到代码中,编译得到最终hex文件,发给老板,完工。

    改进:后续争取优化步骤中第2、3、4步可以不需要任何硬件板子,只通过修改软件即可。做个广告,有这方便需求或者可以联系171049129@qq.com,技术讨论留言即可。如果这样,

    优点:

    1. 提供两级密钥方案,破解难度大
    2. 方便
    3. 简单

    方案

    一级密钥

    一级密钥比较简单,就是通过MCU ID计算累加和得到的数,以STM32为例子,STM32一级密钥可以简单设计为三个ID的和,主要是判定该ID是否注册。

    一级密钥的算法不用太复杂,因为如果没有后续的二级密钥保护,一级密钥太容易被破解,破解成本也很低。

    一级密钥的设置文件为chkMCUID.c

    二级密钥

    二级密钥密钥主要是为了保护一级密钥而设计的。二级密钥通过异或、和、CRC等其他自定义算法,计算一级密钥代码chkMCUID.c存放的FLASH空间数据,判定这些数据是否被改动。

    补充知识:chkMCUID.c首先编译生成chkMCUID.o,然后将chkMCUID.o链接到指定FLASH空间地址。

    二级密钥由于是保护一级密钥的FLASH空间数据,所以首先需要确定一级密钥的FLASH存放空间,修改.sct文件

    这里分配一段单独的FLASH空间LR_IROM2存放一级密钥的RO数据段。编译代码通过.map文件查看该数据段的使用情况。

    大牛攻城狮使用的MCU FLASH比较大,有1M,所以LR_IROM2分配的也比较大,实际可以根据自己使用的MCU FLASH大小配置LR_IROM2的大小。从map文件可以看出来LR_IROM2仅仅使用0xe0大小,如果不增加chkMCUID.c中代码和const变量(不更换编译器、优化等级),map文件中这个size是保本上不变的

    这里是把chkMCUID.o的RO段存放到FLASH其实地址为0x080f0000,最大空间地址为0x00010000,这里通过map文件可以看到只使用0x000000e0。这里如果不增加chkMCUID.c中代码和const变量(不更换编译器、优化等级),map文件的Size都是固定的。

    计算二级密钥FLASH的两种算法,一种是异或算法,另一种是和校验算法,还可以加入自己定义算法。

    main函数

    每次烧录新的板子,都需要新的ID号、一级密钥、二级密钥。

    ID号的获取随便一个读ID的程序就可以,一般老板、硬件或调试人员也会告诉你;

    一级密钥,可以用计算器,珠心算等方式得到;

    二级密钥稍微复杂一点,也是根据你自己二级密钥采用的算法复杂度决定的。

    main演示了如果计算二级密钥XOR/Sum值。实际使用,后续可以更加方便使用上位机软件自动计算出来二级密钥XOR/Sum。

    使用示例

    将一级密钥和ID填入代码编译下载,(这里一级密钥为三个ID和,比较容易计算)串口打印数据如下:

    将打印出来的二级密钥写入代码

    MCU_FLASH_XOR_RESULT = 0x59, MCU_FLASH_SUM_RESULT = 0x5ecd

    编译下载,得到如下数据,说明二级密钥加载成功。

    实际我们使用中,可以根据需求删减打印数据。

    注意事项

    这里需要着重说明的计算二级密钥XOR/Sum值,不能只是再main函数开始的位置检测,并且进入死循环。这样也容易被破掉。最好再周期任务或者其他代码中也检测一下,如果检测到异常,程序上做一些bug,提醒破解者,即可。

    工程代码

    Talk is cheap. Show me your code.

    后续从工程上薅出来,补上。有需要的评论区留下邮箱,有空发一份过去。(哈哈,不用了。)

    这里把我使用工程贴出来,供大家参考,无积分免费下载,就是希望攻城狮早点用上这种方法,提升自身、行业价值。

    MCU固件加密,以STM32为例提供二级密钥方法,加密过程简单-嵌入式文档类资源-CSDN文库

  • 相关阅读:
    【HTML期末作业】大学生抗疫感动专题网页设计作业 抗疫最美逆行者网页 致敬疫情感动人物网页设计制作
    从 0 实现 logistic 回归
    组件框架网站+demo库+svg库+渐变色库网站+矢量图网站等等
    全面理解Web3.0时代
    hive从入门到放弃(四)——分区与分桶
    程序员在工作之余如何保障收入?兼职才是硬道理!
    Linux安装Anaconda(Anaconda3-2022.10-Linux-x86_64.sh版本)
    adb shell命令
    sshpass命令
    什么是过期域名?做网站用过期域名好不好?
  • 原文地址:https://blog.csdn.net/li171049/article/details/126608143