大牛攻城狮最近遇到了一件伤心的事情,团队辛辛苦苦做板子,被别人拿去抄了,固件也被破了。想起那调代码的日日夜夜,多少辛苦都白费了,感觉这是个弱肉强食的时代,这里也要痛骂那些黑心老板,这样做对吗。只能暗暗怪自己当时图方便,没有把固件安全工作做好。
这里把我使用工程贴出来,供大家参考,无积分免费下载,就是希望攻城狮早点用上这种方法,提升自身、行业价值。
MCU固件加密,以STM32为例提供二级密钥方法,加密过程简单-嵌入式文档类资源-CSDN文库
我也搜了很多针对MCU固件加密的观点,总的来说,大家比较认可的方式是:
先说第一条,加密方法不能太复杂,MCU的计算能力和RAM/ROM资源有限,这是大家都认可的;
其次是第二条,加密方法方便,只要加密多少都会带来一些不方便,软件人员最忌讳的就是不做任何加密手段,你发布的hex文件可以万能烧录,即害了自己、又害了老板、还拉低技术人员价值。
这里插一句题外话,针对方便,不同的角色有不同的理解。我这里完全站在软件攻城狮的角度来说方便。假如现在有量产1000套产品需要烧录,软件攻城狮如果可以自己烧录,那就好搞很多。但是往往现实中,软件攻城狮可能不是这家公司的人员或者不在那个城市,如果直接发hex文件,那怎么保证自己的利益呢?
最后说破解成本,就是针对主流MCU的破解有个基本认识,现在的技术对于基于ID加密的方式还是比较容易破解的,破解成本也不高。
常用的加密方法:
第一:JTAG/SW关闭、设置FLASH不可以读。首先这类方法只是增加一点点破解成本,对于专业破解人员来说,这一步基本上没啥用,2千大洋基本可以读出你的hex文件。JTAG/SW关闭、设置FLASH不可以读,只是最初级的加密方式了。
第二:读取ID,计算出来一个密钥key。根据这个密钥key判定ID是否注册,这种方式也比较容易破解了,可以通过修改获取的hex文件的代码中ID取值地址,这里就不细说,说多了都是泪啊!
条件:已知一批芯片ID,软件攻城狮手上有个对应芯片的开发板或者工程板。
步骤:
改进:后续争取优化步骤中第2、3、4步可以不需要任何硬件板子,只通过修改软件即可。做个广告,有这方便需求或者可以联系171049129@qq.com,技术讨论留言即可。如果这样,
优点:
一级密钥比较简单,就是通过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的两种算法,一种是异或算法,另一种是和校验算法,还可以加入自己定义算法。
每次烧录新的板子,都需要新的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.
后续从工程上薅出来,补上。有需要的评论区留下邮箱,有空发一份过去。(哈哈,不用了。)
这里把我使用工程贴出来,供大家参考,无积分免费下载,就是希望攻城狮早点用上这种方法,提升自身、行业价值。