STM32加密步骤简述

STM32加密的核心就是给代码加上"三把锁":UID唯一ID锁Flash读保护(RDP)锁算法验证锁。我会为你详细说明从硬件、软件到具体操作的全过程。

📋 准备工作

  • 🛠️ 硬件准备

    • STM32开发板 :入门级且支持加密的Nucleo系列就非常适合,比如 Nucleo-F103RBNucleo-G0/G4系列,集成的ST-Link调试器方便连接电脑。

    • USB数据线:用于连接开发板和电脑。

  • 💻 软件准备

    • 集成开发环境 (IDE)STM32CubeIDE (ST官方免费、一体化)或 Keil MDK(业界标准,社区版免费)。个人推荐新手直接使用STM32CubeIDE。

    • 烧录与配置工具STM32CubeProgrammer,这是ST官方用来烧录和配置芯片选项字节(如RDP)的必备工具。

    • 串口调试助手 :用于查看程序输出,推荐使用免费的 VOFA+SSCOM

💡 关键概念速览

在动手前,先快速理解三个核心概念:

  1. UID (唯一ID):每颗STM32芯片出厂时内置的96位唯一ID,不可修改,是软件验证的基石。

  2. RDP (读保护) :芯片的硬件"防盗门",通过选项字节 (Option Bytes) 配置。分为三个级别:

    • Level 0 (无保护):默认状态,调试口可随意读写Flash。

    • Level 1 (使能读保护)量产标准配置。禁止调试口访问Flash,解除保护将触发全片擦除。

    • Level 2 (禁止调试):芯片调试接口永久关闭,不可逆,除非极端高安全需求,一般不用。

🛠️ 分步实操:给STM32加上三把锁

第一把锁:硬件读保护 (RDP) - 防止固件被直接读出
  1. 打开并连接

    • 启动 STM32CubeProgrammer

    • 在右侧选择 ST-LINK 并点击 Connect

  2. 进入选项字节配置

    • 点击软件顶部的 Option Bytes 标签页。

    • 点击 Read 按钮,软件会读出并显示当前芯片的配置。

  3. 设置读保护等级

    • Read Out Protection 下拉菜单中,将默认的 Level 0 改为 Level 1
  4. 生效并验证

    • 点击 Apply 按钮,软件会弹出警告窗口,点击 OK 确认。

    • 稍等片刻,软件会提示断开并重连。此时,任何试图读取或写入的操作都会失败,说明保护已生效。

第二把锁:软件唯一ID (UID) 校验 - 防止固件被复制到其他芯片
  1. 生成密钥工程

    • 打开你的IDE (STM32CubeIDE) 新建一个工程。

    • main.c 中编写一个一次性运行的函数,专门用于"签发身份证":

      c

      复制代码
      // 伪代码示例,需要在芯片第一次运行时执行,并将结果写入Flash。
      void Generate_Key_Once(void) {
          uint32_t u_id[3]; // 用于存储UID的三个32位字
          // 假设UID从地址0x1FFF7A10开始,不同系列地址可能不同,请查阅手册
          u_id[0] = *(uint32_t *)(0x1FFF7A10);
          u_id[1] = *(uint32_t *)(0x1FFF7A14);
          u_id[2] = *(uint32_t *)(0x1FFF7A18);
          
          // 使用UID和一些自定义的“盐”值来生成密钥
          uint8_t key[16];
          Generate_Key_From_UID(u_id, "Your_Secret_Salt", key);
          
          // 将生成的密钥写入Flash的最后几页,供以后校验
          Write_Key_To_Flash(key);
          
          // 写入一个标志,表示“已经签发过身份证了”,避免重复执行
          Write_Flag_To_Flash(0x5A5A5A5A);
      }
    • 将这个程序烧录到你的开发板上运行一次,使其将生成的密钥存入Flash。

  2. 校验密钥工程

    • 修改 main.c,在程序最开始添加校验函数:

      c

      复制代码
      // 伪代码示例,必须在所有用户功能之前执行
      int Check_Key(void) {
          // 1. 检查是否已生成密钥的标志
          if (Read_Flag_From_Flash() != 0x5A5A5A5A) {
              // 若标志不存在,说明是未初始化的芯片,可拒绝运行或进入恢复模式
              return 0; 
          }
          
          // 2. 重新读取UID
          uint32_t u_id[3];
          Read_UID(u_id);
          
          // 3. 使用完全相同的算法,重新计算预期的密钥
          uint8_t expected_key[16];
          Generate_Key_From_UID(u_id, "Your_Secret_Salt", expected_key);
          
          // 4. 读取Flash中之前存储的密钥
          uint8_t stored_key[16];
          Read_Key_From_Flash(stored_key);
          
          // 5. 比较两者是否一致
          if (memcmp(expected_key, stored_key, 16) != 0) {
              // 密钥不匹配!说明固件被复制到了别的芯片,启动“自毁”或“迷惑”程序
              while(1); // 进入死循环
          }
          return 1; // 校验通过
      }
    • 点击 Build 按钮编译工程

第三把锁:最终烧录与启用

这是量产前的最后一步,目的是将校验逻辑和读保护结合,让固件坚不可摧。

  1. 烧录含UID校验的固件 :使用STM32CubeProgrammer将上一步编译好的固件烧录进开发板。

  2. 启用第一把锁(RDP Level 1) :重复"第一把锁"的步骤,在 Option Bytes 中再次将读保护设置为 Level 1Apply

  3. 最终验证:断开并重连STM32CubeProgrammer,如果一切顺利,它会报告无法访问,代表加密成功。

🚀 进阶保护:为固件穿上"防弹衣"

完成以上三步,你的固件安全级别已经很高了。如果想更进一步,可以考虑:

  • 启用写保护 (WRP):和设置RDP在同一界面,勾选需要保护的Flash扇区即可。

  • 代码混淆:让攻击者难以逆向分析。

  • 添加"反调试"代码:检测调试寄存器,一旦发现即让程序停止或自毁。

📌 几点提醒

  • RDP Level 1是量产首选:它提供了足够的安全性,同时允许通过全片擦除的方式来"解锁"返修品,适合量产和维修流程。

  • RDP Level 2极难恢复:一旦设置,芯片基本报废。在量产初期请勿使用,在最终产品定型且确定不再需要调试时,才有必要考虑。

  • 密钥"盐值"是最高机密 :代码中生成密钥时使用的"盐值"Your_Secret_Salt是核心机密,务必保管好。

  • 务必先测试后量产:在大批量生产前,一定要用几块板子完整地走一遍上述流程,确保万无一失。

  • 善用ST官方工具:新系列STM32H5、U5等支持更高级的安全固件安装(SFI),可直接烧录加密后的固件,实现端到端的安全。

加密是一个系统工程,没有绝对的安全,只有不断提高的破解成本。

相关推荐
恶魔泡泡糖3 小时前
stm32F103C8T6标准库流水灯1——输出模式
stm32·单片机·嵌入式硬件
風清掦6 小时前
【江科大STM32学习笔记-11】SPI通信协议 - 11.2 软件SPI读写W25Q64
笔记·stm32·单片机·嵌入式硬件·学习
LCG元7 小时前
STM32实战:基于STM32F103的智能饮水机温度控制
stm32·单片机·嵌入式硬件
yongui478347 小时前
STM32 上实现 SPI 自发自收(Loopback)
stm32·单片机·嵌入式硬件
弘毅 失败的 mian7 小时前
STM32 时钟详解
经验分享·笔记·stm32·单片机·嵌入式硬件·嵌入式
jghhh018 小时前
STM32 控制 3 个步进电机方案
stm32·单片机·嵌入式硬件
Wave8458 小时前
STM32 串口通信 (UART) 全栈底层复习指南
stm32·单片机·嵌入式硬件
WeeJot嵌入式8 小时前
【IIC】IIC通信与温湿度传感器AHT20(DHT20)
stm32·单片机·嵌入式硬件·嵌入式·iic
WeeJot嵌入式8 小时前
【串口】蓝牙模块与简易数据包解析
stm32·单片机·嵌入式硬件·蓝牙