MCU程序加密保护(一)闪存读写保护法 加密与解密

MCU(微控制器单元)的加密方法可以从硬件、软件和通信协议三个层面来理解。以下是常见的MCU加密手段,按类型分类说明:

针对目前 STM32 系列微控制器在程序加密保护方面手段单一、保护效果有限的问题,本文介绍并分析了四种常用的程序保护方法:

  1. 闪存读写保护

  2. 芯片唯一 ID 验证

  3. 外接加密芯片

  4. 引导程序加密(Bootloader 加密)

实际在 STM32 开发板上的测试表明,合理组合多种保护机制,能显著增强芯片程序与数据的安全性,有效防止闪存程序被读取、拷贝或篡改,为嵌入式系统提供更可靠的安全保障。 

1 闪存读写保护法

STM32 微控制器提供了闪存读写保护的功能,

用来防止对闪存的非法访问。 闪存读写保护功能概述:

读保护(RDP)

  • 通过修改 Option Bytes 中的 RDP 位来启用。

  • 启用后,Flash 只能被内部正常执行的程序读取,无法通过 JTAG/SWD 调试接口或从 RAM 启动的程序读取。

  • 解除读保护会触发整片 Flash 擦除,防止逆向工程与调试工具破解。

  • 以 STM32L1 系列为例,RDP 分为 3 个等级,不同等级对应不同的安全强度。

等级描述
0无保护(默认)。可以通过 JTAG/SWD 或从 RAM 启动的程序任意读取 Flash。
1Flash 受保护,防止由调试器(JTAG/SWD)直接读取,也不能通过在 RAM 中加载执行程序来读取。
解除 Level 1 保护将触发全片擦除。
2最严格保护——禁用所有调试功能。
一旦设为 Level 2,不可复原,需谨慎使用。

写保护(WRP)

  • 通过在 Option Bytes 中设置 WRP 位来启用。

  • 启用后,对被保护页的任何写或擦除操作都会被硬件阻止,并在状态寄存器中产生错误标志。

  • 可以防止恶意修改中断向量表或关键代码区域。

优缺点对比:

优点

由硬件层面直接提供,成本为零,易于配置。

能有效防止通过调试接口的非法读写

缺点

单一的读/写保护难以抵抗高级物理攻击或侧信道分析。

需要与软件层面的校验(如 CRC、HASH)或更高级的加密方法(如外部加密芯片、Bootloader 加密)组合,才能构建更完善的防护体系。

实施的方法如下,下面以 STM32G4 系列为例,分别介绍如何通过 ST-Link/CubeProgrammer 工具以及 运行时(HAL)编程 两种方式来启用 Flash 的读写保护(RDP 和 WRP)。

方法一:通过 STM32CubeProgrammer 界面设置

打开 CubeProgrammer

启动 STM32CubeProgrammer,选择 “ST-Link” 连接。

读取当前 Option Bytes

在左侧菜单选择 “Option Bytes”

点击 “Read”,查看当前 RDP(Read Protection)和 WRP(Write Protection) 配置。

配置读保护(RDP)

“Read protection” 下拉框中选择:

Level 0:无保护

Level 1:Flash 只允许内部执行读取

Level 2:全部调试接口禁用(不可逆)

推荐一般项目选 Level 1

配置写保护(WRP)

“Write protection” 区域,勾选你要保护的 Flash 扇区(Page)。

比如要保护第 0~3 扇区,就勾选对应页号。

写入并重启

点击 “Apply”,CubeProgrammer 会提示需要复位芯片以生效。

确认后,设备重启,Option Bytes 即更新完毕。

方法二:在用户代码中动态配置(HAL 库示例)

如果希望在程序首次运行时,或通过 Bootloader 进行保护设置,可以在固件内部调用 HAL API 来修改 Option Bytes。

/*** @brief  启用 RDP Level1 并对指定扇区启用写保护* @note   必须在系统启动早期执行,且芯片复位后才生效*/
void Protect_Flash(void)
{HAL_FLASH_Unlock();HAL_FLASH_OB_Unlock();/* 1) 读保护 → Level1 */FLASH_OBProgramInitTypeDef OBInit = {0};OBInit.OptionType = OPTIONBYTE_RDP;OBInit.RDPLevel   = OB_RDP_LEVEL_1;if (HAL_FLASHEx_OBProgram(&OBInit) != HAL_OK) {/* 错误处理 */}/* 2) 写保护 → 保护第 0~15 KB(页 0~15) */memset(&OBInit, 0, sizeof(OBInit));OBInit.OptionType = OPTIONBYTE_WRP;OBInit.WRPState   = OB_WRPSTATE_ENABLE;OBInit.WRPPage    = OB_WRP_PAGES0TO3   | OB_WRP_PAGES4TO7   | OB_WRP_PAGES8TO11  | OB_WRP_PAGES12TO15;if (HAL_FLASHEx_OBProgram(&OBInit) != HAL_OK) {/* 错误处理 */}HAL_FLASH_OB_Lock();HAL_FLASH_Lock();//    /* 复位生效 */
//    NVIC_SystemReset();
}

 其次你会发现程序也烧写不进去。此时目标也达成。

我们说了加密,那如何解密呢?问题在于每次切换RDPLevel 1到0的过程中的时候,会将flash的内容全部擦除。因此这是解密的难点之一。

我们引入思考点一,针对闪存读写保护法这类内容也就是寄存器置位,如果你要切换RDP1到RDP0 的过程伴随着一个问题,STM32 上的 Read-Out Protection(RDP)并不是真正的“加密”,而是一种硬件级的“只读保护”机制——它保证 任何 试图“解开”这层保护的操作(也就是把 RDP 从 Level 1 降回 Level 0),都会触发一次整片 Flash 的 不可逆擦除,从而根本不可能在芯片上恢复出原来的固件!!!

一旦启用 RDP Level 1,就不可能在器件内“解密”或“读取” Flash 内容;任何试图取消保护的行为都会把所有数据抹掉。

为什么不能“解密”现有固件???

STM32 的 RDP 设计上就是「不可逆保护」:降级就擦除。

Flash 中的代码以明文形式存储,Option Bytes 保护只是阻止「直接」访问,但并不做真实的加密。

一旦需要「访问明文」,只能通过内部执行(CPU 跳转),而不是通过调试器或外部读口。

因此问题点来了!!!我们要做的是,在启用了 RDP Level 1 以后,所有基于 JTAG/SWD外部调试器 的直接读 Flash 操作都会被阻止——硬件层面上不可能再通过外部工具把 Flash 整片“拷”出来。不过,RDP Level 1 并不影响 MCU 自身程序对 Flash 的正常读取;换句话说,你只要在芯片内跑一段用户代码,通过 UART/CAN/USB 等总线把 Flash 内容“转发”出去,就能获得完整的二进制镜像。

首先我们要将程序运行在SRAM中,根据自己的芯片主控观察大小,笔者这边是20KB的如下所示:

因此我们的环境在keil,如何配置呢,跟着笔者一步一步来吧。

第一步就是新建立一个模板了 如上所示,我们进行切换。

其次就是宏定义了,加上下述内容!

这边就是改配置内容了

接下来就是这个内容的更改了,配置文件具体如何写如下所示:

LR_IROM1 0x20000000 0x00005000  {    ; Total 20KB SRAM regionER_IROM1 0x20000000 0x00003000  {  ; Code section: 12KB*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO).ANY (+XO)}RW_IRAM1 0x20003000 0x00002000  {  ; Data section: 8KB.ANY (+RW +ZI)}
}

其次就是这个仿真器命令文件了,如下所示:

具体内容如下所示:

/***********************************************************/
/* Debug_RAM.ini: Initialization File for Debugging from Internal RAM         */
/******************************************************/
/* This file is part of the uVision/ARM development tools.                    */
/* Copyright (c) 2005-2014 Keil Software. All rights reserved.                */
/* This software may only be used under the terms of a valid, current,        */
/* end user licence from KEIL for a compatible version of KEIL software       */
/*development tools. Nothing else gives you the right to use this software  */
/***************************************************/FUNC void Setup (void) {
SP = _RDWORD(0x20000000); // 设置栈指针SP,把0x20000000地址中的内容赋值到SP。
PC = _RDWORD(0x20000004); // 设置程序指针PC,把0x20000004地址中的内容赋值到PC。
_WDWORD(0xE000ED08, 0x20000000);  // Setup Vector Table Offset Register
}LOAD %L INCREMENTAL                    // 下载axf文件到RAM
Setup();                           //调用上面定义的setup函数设置运行环境//g, main   //跳转到main函数,本示例调试时不需要从main函数执行,注释掉了,程序从启动代码开始执行

最后就是debug处了。

之后进入调试你会发现程序在SRAM的运行处。观察汇编代码。

因此,程序成功在SRAM处运行。

都要重新点击“Debug”按钮下载SRAM程序,再全速运行才能正常查看输出。

接着就是写拷贝flash的内容到SRAM处通过UART转发出来。

这是原本的程序地址所示如下了。

如下是通过SRAM来拷贝Flash转发到uart的内容

void dump_flash_via_uart(void)
{char hex_str[8];for (uint32_t addr = FLASH_START_ADDR; addr < (FLASH_START_ADDR + FLASH_SIZE_BYTES); addr++) {uint8_t byte = *(volatile uint8_t*)addr;sprintf(hex_str, "%02X ", byte);  // 格式化成十六进制字符串HAL_UART_Transmit(&huart1, (uint8_t*)hex_str, strlen(hex_str), HAL_MAX_DELAY);}const char* end_msg = "\r\n[FLASH DUMP DONE]\r\n";HAL_UART_Transmit(&huart1, (uint8_t*)end_msg, strlen(end_msg), HAL_MAX_DELAY);
}
含义十六进制值小端转换(实际值)
初始栈地址 MSPF8 04 00 200x200004F8
Reset_Handler05 01 00 080x08000105
NMI_Handler?5B 13 00 080x0800135B
HardFault_Handler?C9 11 00 080x080011C9

这些值完全一致!

但是在WDP与DRP设置了之后。。

📌 根本原因:

✅ 你能正常读取 Flash,是因为:

  • STM32 默认 RDP 是 Level 0(无保护)

  • 此时,即便运行在 SRAM,也能直接访问 0x08000000 地址处的 Flash 内容;

❌ 设置 RDP Level 1 后:

  • Cortex-M3 核心(STM32F1)硬件禁止访问 Flash 内容

  • 这是芯片的硬件安全特性,即使代码跑在 SRAM,依然无法读取 Flash 数据,目的就是为了防止“SRAM 下载程序+读取 Flash 代码”这种逆向手段;

因此上述破解方案无效,无法再从芯片内部获取任何 Flash 数据了,数据已经从访问层面彻底封锁。如果想切回回0,flash内容也会全部擦除!

方法原理是否可行备注
芯片解封/酸蚀 + 显微探测打开芯片封装,用电子显微镜直接读 Flash 电荷状态✔️理论可行需要实验室级别设备、极高技术
功耗分析(侧信道攻击)用高精度设备分析芯片运行时功耗波动,推测程序数据理论可行,但难度极高适用于破解算法或加密密钥,不适合整段程序恢复
激光/聚焦扫描干扰用激光打干扰点,欺骗 Flash 控制器读取受保护数据✔️高端实验室可能可行用于芯片逆向取证等高价值目标
IC 解封 + Flash 直接读出拆解裸片,对 Flash 数字结构逐位扫描✔️有可能,但需要芯片内部结构图这属于“物理攻击”范畴

⚠️ 这些都需要 IC 物理逆向实验室、百万级设备成本,不具备民用可行性。

手段原理应用场景
X-Ray(X 射线扫描)非破坏式探测芯片内部结构,识别 layout,理论可判断 Flash 存储逆向分析芯片、找 ROM Mask
开盖 + 紫外线(UV)曝光对芯片裸露的 silicon 层曝光,激发电荷或使 EEPROM 状态改变用于清除 EEPROM 或恢复旧锁定状态

补充:

STM32 跟一些 MCU(比如 AVR、ESP32)那种通过 熔丝(fuse)位 永久写死不同。

STM32 的 Option Bytes 是可擦除/可重写的 Flash 区域

只不过 RDP Level 2 一旦写入,就不可降级、无法还原;

RDP Level 1 还可以通过 全芯片擦除 恢复成 Level 0(但数据没了)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/81297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汽车装配又又又升级,ethernetip转profinet进阶跃迁指南

1. 场景描述&#xff1a;汽车装配线中&#xff0c;使用EtherNet/IP协议的机器人与使用PROFINET协议的PLC进行数据交互。 2. 连接设备&#xff1a;EtherNet/IP机器人控制器&#xff08;如ABB、FANUC&#xff09;与PROFINET PLC&#xff08;如西门子S7-1500&#xff09;。 3. 连…

RFID系统:技术解析与应用全景

一、技术架构与运行逻辑 RFID&#xff08;Radio Frequency Identification&#xff09;系统通过无线电波实现非接触式数据交互&#xff0c;其核心由三部分组成&#xff1a; 电子标签&#xff08;Tag&#xff09;&#xff1a; 无源标签&#xff1a;依赖读写器电磁场供电&…

25、DeepSeek-R1论文笔记

DeepSeek-R1论文笔记 1、研究背景与核心目标2、核心模型与技术路线3、蒸馏技术与小模型优化4、训练过程简介5、COT思维链&#xff08;Chain of Thought&#xff09;6、强化学习算法&#xff08;GRPO&#xff09;7、冷启动**1. 冷启动的目的****2. 冷启动的实现步骤****3. 冷启动…

开源项目实战学习之YOLO11:12.2 ultralytics-models-sam-decoders.py源码分析

👉 点击关注不迷路 👉 点击关注不迷路 👉 另外,前些天发现了一个巨牛的AI人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。感兴趣的可以点击相关跳转链接。 点击跳转到网站。 ultralytics-models-sam 1.sam-modules-decoders.pyblocks.py: 定义模型中的各…

Raft 协议:分布式一致性算法的核心思想

引言 在分布式系统中&#xff0c;数据一致性是核心挑战。Raft 协议作为一种易于理解的一致性算法&#xff0c;被广泛应用于 etcd、Consul 等系统中。 一、Raft 核心概念 1.1 角色与任期&#xff08;Term&#xff09; • 领导者&#xff08;Leader&#xff09;&#xff1a;处…

基于DWT的音频水印算法

基于离散小波变换&#xff08;DWT&#xff09;的音频水印算法是一种结合信号处理与信息隐藏的技术&#xff0c;旨在将版权信息或标识隐蔽地嵌入音频信号中&#xff0c;同时保证不可感知性和鲁棒性。以下是该算法的核心步骤及关键技术点&#xff1a; ​1. 算法基本原理​ ​DWT…

低空经济发展现状与前景

低空经济发展现状与前景 一、低空经济的定义与范畴 低空经济是以民用有人驾驶和无人驾驶航空器为主体&#xff0c;以载人、载货及其他作业等多场景低空飞行活动为牵引&#xff0c;辐射带动商业活动或公共服务领域融合发展的一种综合性新经济形态。其涵盖的低空空域通常为距离…

售前工作.工作流程和工具

第一部分 售前解决方案及技术建议书的制作 售前解决方案编写的标准操作步骤SOP: 售前解决方案写作方法_哔哩哔哩_bilibili 第二部分 投标过程关键活动--商务标技术方案 1. 按项目管理--售前销售项目立项 销售活动和销售线索的跟踪流程和工具 1&#xff09;拿到标书&#xff…

DeerFlow试用

github拉取代码 配置.env和conf.yaml 注意设置大模型的url和模型名称、api_key 先启动根目录下的server&#xff0c;端口如果有冲突直接在default变量赋值时修改&#xff1b; 再启动前端&#xff0c;先build再run dev&#xff1b; 根据前端完成时的地址访问界面&#xff1…

python + streamlink 下载 vimeo 短视频

1. 起因&#xff0c; 目的: 看到一个视频&#xff0c;很喜欢&#xff0c;想下载。https://player.vimeo.com/video/937787642 2. 先看效果 能下载。 3. 过程: 因为我自己没头绪。先看一下别人的例子&#xff0c; 问一下 ai 或是 google问了几个来回&#xff0c;原来是流式…

JavaScript【6】事件

1.概述&#xff1a; 在 JavaScript 中&#xff0c;事件&#xff08;Event&#xff09;是浏览器或 DOM&#xff08;文档对象模型&#xff09;与 JavaScript 代码之间交互的一种机制。它代表了在浏览器环境中发生的特定行为或者动作&#xff0c;比如用户点击鼠标、敲击键盘、页面…

【Java ee初阶】HTTP(2)

一、HTTP的方法 方法 说明 支持的HTTP协议版本 GET 获取资源 1.0、1.1 POST 传输实体主体 1.0、1.1 PUT 传输文件 1.0、1.1 HEAD 获得报文首部 1.0、1.1 DELETE 删除文件 1.0、1.1 OPTIONS 询问支持的方法 1.1 TRACE 追踪路径 1.1 CONNECT 要求用隧道…

文件名是 ‪E:\20250512_191204.mp4, EV软件录屏,未保存直接关机损坏, 如何修复?

去github上下载untrunc 工具就能修复 https://github.com/anthwlock/untrunc/releases 如果访问不了 本机的 hosts文件设置 140.82.112.3 github.com 199.232.69.194 github.global.ssl.fastly.net 就能访问了 实在不行&#xff0c;从这里下载&#xff0c;传上去了 https://do…

腾讯 CodeBuddy 杀入 AI 编程赛道,能否撼动海外工具霸主地位?

在 AI 编程助手领域&#xff0c;海外的 Cursor 等工具风头正劲&#xff0c;如今腾讯带着 CodeBuddy 隆重登场&#xff0c;国产 AI 编程助手能否借其之力崛起&#xff1f;让我们一探究竟。 官网&#xff1a; 腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 实战安装教程 …

PySide6 GUI 学习笔记——常用类及控件使用方法(常用类颜色常量QColorConstants)

文章目录 一、概述二、颜色常量表标准 Qt 颜色SVG 颜色&#xff08;部分&#xff09; 三、Python 代码示例四、代码说明五、版本兼容性六、延伸阅读 一、概述 QColorConstants 是 Qt for Python 提供的一个预定义颜色常量集合&#xff0c;包含标准Qt颜色和SVG规范颜色。这些常…

MATLAB 自然语言处理入门教程

文章目录 前言环境配置一、MATLAB NLP 工具箱概述二、核心功能与 API1. 文本数据准备2. 特征提取3. 文本分类&#xff08;传统机器学习&#xff09;4. 深度学习文本分类&#xff08;LSTM&#xff09; 三、实战案例&#xff1a;情感分析四、高级应用1. 命名实体识别&#xff08;…

C++ deque双端队列、deque对象创建、deque赋值操作

在deque中&#xff0c;front()是头部元素&#xff0c;back()指的是尾部元素。begin()是指向头部的迭代器&#xff0c;end()是指向尾部的下一个元素的迭代器。 push_front 头部进行插入 pop_front 尾部进行删除 push_back 尾部进行插入 pop_back 尾部进行删除 deque如果同时…

java每日精进 5.15【分页实现】

1. 什么是对象转换和数据翻译&#xff1f; 对象转换 对象转换是指将一种类型的对象&#xff08;如数据库实体 UserDO&#xff09;转换为另一种类型的对象&#xff08;如前端响应对象 UserVO 或服务层 DTO&#xff09;。例如&#xff0c;一个 UserDO 包含用户 ID、姓名和部门 …

什么是API接口?API接口的核心价值

随着互联网技术的蓬勃发展&#xff0c;API 接口作为不同应用程序之间的关键纽带&#xff0c;其重要性愈发凸显。本文将从专业视角&#xff0c;深入剖析 API 接口的分类、原理、请求方式以及安全机制等核心要素&#xff0c;助力读者全面理解这一数字化基础设施。 一、API 接口及…

Linux_ELF文件

目录 前言&#xff1a; 一、ELF文件的类型 二、ELF文件的组成格式 1. ELF头部(ELF Header) 2. 节头表(Section Header Table) 3. 程序头表(Program Header Table) 4. 节(Sections)与段(Segments) 三、ELF文件从形成到加载轮廓 1、ELF可执行文件形成过程 2、 可执行文…