小福利:分享一个STM32加密的思路 有源码

2019-12-09 19:18发布

本帖最后由 射天狼 于 2019-9-20 09:27 编辑

产品里STM32现在用的越来越多了板子防被人抄这个目前我还没什么好办法,知道的坛友可以分享一下
只能从代码上做一个简单的加密,可以防止一大部分人轻易获取到程序。然后抄板、hex下载一条龙式的什么服务

思路利用stm32里全球唯一ID 加一个CRC16 如果有EEPROM可以也加上  也可以再加FLASH读保护
1.第一次上电流程:判断是不是第一次上电(FLASH里都是0xFF)如果是那就在自定义地址写入ID+CRC16 有EEPROM也一块写入
2.以后开机流程:直接比对STM32里的ID和FLASH里的ID 和EEPROM的ID是否完全一样,不一样 呵呵呵···while(1);伺候(也可以给个笑脸-_-)

加密原理:
如果为复制代码:上电因为FLASH是复制进去的 所以FLASH里的ID还是原来STM32的 这样和新STM32里读取的ID不一致 还是老规矩···

上代码:
  1. //////////////////////加密程序开始//////////////////////
  2. #define EEPROM
  3. //        FLASH_Unlock();
  4. ////  FLASH_ReadOutProtection(DISABLE);
  5. //        FLASH_ReadOutProtection(ENABLE);//读输出保护
  6. //        FLASH_Lock();
  7. #ifdef EEPROM
  8. WP_L;   //读取EEPROM里的ID和CRC
  9. for(i=0; i<14; i++) {
  10.     I2C_ReceiveData(0xA2,0x1000+i, HAV_H,&UID_E[i], 1);//u8
  11. }
  12. WP_H;
  13. #endif
  14. Get_ChipID();
  15. crc = crc16_ccitt(UID, 12); //校验前12个字节 最后两个字节CRC16校验
  16. UID[12]=(*(char *)(&crc));
  17. UID[13]=(*((char *)(&crc) + 1));

  18. STMFLASH_Read(0x803FF00,(u16*)UID_F,7); //最后一个16个字节是CRC16校验
  19. //        check(1, &UID_F[0],12));
  20. crc = crc16_ccitt(UID_F, 12); //校验前12个字节 最后两个字节CRC16校验
  21. UID_F[12]=(*(char *)(&crc));
  22. UID_F[13]=(*((char *)(&crc) + 1));

  23. //        Unique_temp=*(vu32 *)UID_F;//stm32小端 0x12 0x34 0x56 0x78 Unique_temp为0x78563412

  24. //如果FLASH是第一次下载 先写入读取的ID到FLASH和EEPROM
  25. if(UID_F[0]==0xff && UID_F[1]==0xff && UID_F[2]==0xff && UID_F[3]==0xff) {
  26.     STMFLASH_Write(0x803FF00,(u16*)UID,7);
  27. #ifdef EEPROM
  28.     //也写一次EEPROM 三方对比
  29.     WP_L;   //保存校准值到eeprom
  30.     for(i=0; i<14; i++) {
  31.         I2C_SendData(0xA2,0x1000+i, HAV_H,&UID[i], 1);//u8
  32.     }
  33.     WP_H;
  34. #endif
  35. } else { //开始对比ID和FLASH、EEPROM是否相同
  36.     for(i=0; i<14; i++) {
  37.         if(UID[i]!=UID_F[i]) {
  38.             display_string_12x32(68,2, "ERROR",5,0);
  39.             while(1);
  40.         }
  41.     }
  42. #ifdef EEPROM
  43.     for(i=0; i<14; i++) {
  44.         if(UID[i]!=UID_E[i]) {
  45.             display_string_12x32(68,2, "ERROR",5,0);
  46.             while(1);
  47.         }
  48.     }
  49. #endif
  50. }
  51. //////////////////////加密程序结束//////////////////////
复制代码


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
85条回答
wajlh
1楼-- · 2019-12-15 14:28
bailao99 发表于 2019-9-20 14:42
加密芯片的使用思路见下图,感觉不靠谱

你说的这个是非常早期的加密芯片,提供一个ID经过一定算法以后,返回给主MCU, 现在很多加密芯片都能运行用户代码了。
aming2046
2楼-- · 2019-12-15 19:19
 精彩回答 2  元偷偷看……
落叶知秋
3楼-- · 2019-12-15 22:29
这个话题在论坛以前就讨论过好几次了,最终结果也没得出个所以然来
nanfang2000
4楼-- · 2019-12-15 23:59
成本最低效果又好的方法是不要每次检测,而是一定次数或者一定时间之后再检测,这叫暗桩。如果弄成随机更好。破解者想破解必须等待校验出现才好跟踪,而且还有没有暗桩他心里也没底
bailao99
5楼-- · 2019-12-16 03:51
wajlh 发表于 2019-9-20 14:51
你说的这个是非常早期的加密芯片,提供一个ID经过一定算法以后,返回给主MCU, 现在很多加密芯片都能运行 ...

可以推荐下好用便宜的加密芯片吗?
canspider
6楼-- · 2019-12-16 07:06
本帖最后由 canspider 于 2019-9-20 16:14 编辑

破解流程一般是把bin读出来
然后找一块相同的片子,把bin刷进去,如果能正常运行,破解完成,如果不能,继续往下走
用调试器把bin下进去开始调试,先在读保护开关处下内存断点,遇到后屏蔽掉相关代码
再在UID读写处下内存断点,不管你之前是怎么算的,你最后总得有一条指令去访问UID吧
找到后直接改成访问flash某个地址的,在这个flash地址写上UID

要防的话只能让设备90%都正常工作,偶尔出一下错,让别人尽量不要先怀疑到唯一ID上来

53楼说的暗桩就是比较好的办法,并且尽量让错误不那么明显。

一周热门 更多>