H7-TOOL脱机烧录的UID加密操作方法,支持一键生成目标板C代码,方便大家轻松操作(2024-08-20,已发布)

本文主要是介绍H7-TOOL脱机烧录的UID加密操作方法,支持一键生成目标板C代码,方便大家轻松操作(2024-08-20,已发布),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

UID加密使用比较方便,对应的C代码模板已经做好,使用TOOL上位机生成后,直接复制粘贴到自己的工程即可使用。返回1表示解密成功,返回0表示失败。
 

【UID加密原理】

1、烧录器在烧录芯片时,按照指定的算法将UID码编码为一个加密数据,并写入FLASH指定区域。
2、用户的程序必须增加一段UID校验程序比较UID和加密数据是否满足算法规则,不满足则停止运行或呈现随机错误。
3、用户程序只要进行了UID加密,就可以防止初级盗版者直接复制程序到其他芯片。
4、用户可以自行修改加密算法,以增加保密性。

点击上位机这个按钮可以查看了解:


【UID界面功能介绍】


1、算法公式

当前做了三个
(1)encrypt_001.lua,  这个最安全,对UID做了各种加密,当前支持的一键C文件生成也是基于这个制作,大家配置的时候要选择这个选项
(2)encrypt_copy_uid.lua, 这个最简单,就是单纯的读取UID,未对UID做加密处理。
(3)encrypt_crc32_uid.lua, 这个是对UID做了简单的CRC32方式加密。

本贴的实现是基于第1中UID加密,实际应用也推荐用这种。


2、参数名A1 -A16,每个参数值范围1 - 16
 

这里默认即可,一般无需修改


3、选择算法随机数

这个的对应关系是这样的,  一个选项对应一个:


4、算法函数用的常量

这里是8bit的hex,推荐配置8个值即可,  每个值范围0x00 - 0xFF


5、随机数

随机数1,随机数2,随机数3,随机数4设置都是一样的

以随机数1为例进行说明,可以设置跟随那个分区一起写入

这里的分区是跟前面这里分区对应的:

长度推荐就设置为默认的4,而写入地址,可以根据自己的需要设置。


6、UID加密启用

可以设置跟随那个分区一起写入,与前面第5步的含义一样

长度推荐就设置为默认的4,而写入地址,可以根据自己的需要设置。


【实际操作举例】

使用H7-TOOL给我们的STM32H7开发板加密为例进行说明

1、选择脱机烧录的芯片型号,优先配置UID,生成UID加密算法的C实现


 

2、点击这里生成C算法:

#include <stdio.h>
#include <stdlib.h>
#include "stdint.h"
#include <string.h>/*
*********************************************************************************************************
*                                           定义
*********************************************************************************************************
*/
typedef struct {uint32_t enable;  // 使能位uint32_t address; // 存储地址uint32_t length;  // 随机数长度
} RNG_TAB_t;uint8_t UidArray[16] = {0};
uint8_t EncryptUidArray[16] = {0};
uint8_t ReEncryptUidArray[16] = {0};/*
*********************************************************************************************************
*                                 通过上位机更新,与上位机保持一致
*********************************************************************************************************
*//*--PC_DEFINE_BEGIN--*/#define A1   1
#define A2   2
#define A3   3
#define A4   4
#define A5   5
#define A6   6
#define A7   7
#define A8   8
#define A9   9
#define A10   10
#define A11   11
#define A12   12
#define A13   13
#define A14   14
#define A15   15
#define A16   16#define ENCRYPT_ADDR     0x08100000  //UID加密数据存储地址
#define ENCRYPT_LEN      8 //加密结果长度#define ENCRYPT_RND_IDX  0   //加密用初值选择 0:固定数,1-4是随机数
#define RNG_CONST_DATA = "11 22 33 44 55 66 77 88"   //常量值
#define RNG_TAB_t RNG_TAB = {     //使能位, 存储地址, 随机数长度{0, 0x08000000, 4},{0, 0x08000000, 4},{0, 0x08000000, 4},{0, 0x08000000, 4}
};#define UID_ADDR  0x1FF1E800
#define UID_BYTES 12/*--PC_DEFINE_END--*//*
*********************************************************************************************************
*                                             UID相关API
*********************************************************************************************************
*/
static uint8_t stringToHexArray(const char *str, uint8_t *hexArray) 
{uint32_t  index = 0;while (*str != '\0') {while (*str == ' ') {str++;}if (*str == '\0') {break;}sscanf(str, "%2hhx", &hexArray[index++]);str += 2;}return index;
}/*
*********************************************************************************************************
*        函 数 名: encrypt
*        功能说明: 计算UID加密
*        形    参: ---
*        返 回 值: 无
*********************************************************************************************************
*/
static void encrypt(const uint8_t* _uid, const uint8_t* _rnd, uint8_t _rndsize, uint8_t* out) 
{uint8_t uid[16] = {0};uint8_t rnd[16] = {0};int i, j;if (_uid == NULL) {return;}for (i = 0; i < UID_BYTES; i++) {uid[i] = _uid[i];}j = 0;for (i = UID_BYTES; i < 16; i++) {uid[i] = uid[j++];}if (_rnd != NULL) {for (i = 0; i < _rndsize; i++) {rnd[i] = _rnd[i];}}out[0] = uid[A1 - 1] ^ (uid[A2 - 1] >> 1) ^ (uid[A3 - 1] >> 1);out[1] = uid[A4 - 1] ^ (uid[A5 - 1] >> 0) ^ (uid[A6 - 1] >> 1);out[2] = uid[A7 - 1] ^ (uid[A8 - 1] >> 1) ^ (uid[A9 - 1] >> 3);out[3] = uid[A10 - 1] ^ (uid[A11 - 1] >> 2) ^ (uid[A12 - 1] >> 0);out[4] = uid[A1 - 1] ^ (uid[A10 - 1] << 1) ^ (uid[A2 - 1] >> 0);out[5] = uid[A4 - 1] ^ (uid[A7 - 1] << 1) ^ (uid[A5 - 1] << 2);out[6] = uid[A7 - 1] ^ (uid[A4 - 1] >> 0) ^ (uid[A8 - 1] << 0);out[7] = uid[A10 - 1] ^ (uid[A1 - 1] >> 2) ^ (uid[A11 - 1] << 1);out[8] = uid[A2 - 1] ^ (uid[A10 - 1] >> 1);out[9] = uid[A3 - 1] ^ (uid[A7 - 1] << 1);out[10] = uid[A6 - 1] ^ (uid[A4 - 1] << 1);out[11] = uid[A9 - 1] ^ (uid[A1 - 1] >> 2);out[12] = uid[A1 - 1] ^ (uid[A2 - 1] >> 1);out[13] = uid[A3 - 1] ^ (uid[A5 - 1] >> 0);out[14] = uid[A6 - 1] ^ (uid[A8 - 1] << 2);out[15] = uid[A9 - 1] ^ (uid[A11 - 1] >> 0);for (i = 0; i < 16; i++) {out[i] ^= rnd[i % _rndsize];}
}/*
*********************************************************************************************************
*        函 数 名: UidCompare
*        功能说明: 比较加密的UID
*        形    参: 1表示成功,0表示失败
*        返 回 值: 反
*********************************************************************************************************
*/
uint8_t UidCompare(void)
{uint8_t tempbuf[16] = {0};uint16_t i;uint8_t size;uint8_t index;        for(i = 0; i < UID_BYTES; i++){UidArray[i] = *(volatile uint8_t*)(UID_ADDR+i);}for(i = 0; i < ENCRYPT_LEN; i++){EncryptUidArray[i] = *(volatile uint8_t*)(ENCRYPT_ADDR + i);}        if(ENCRYPT_RND_IDX == 0){size = stringToHexArray((const char *)RNG_CONST_DATA, tempbuf);encrypt(UidArray, tempbuf, size, ReEncryptUidArray);}else{index = (uint8_t)(ENCRYPT_RND_IDX - 1);for(i = 0; i < RNG_TAB[index].length; i++){tempbuf[i] = *((uint8_t *)(uintptr_t)(RNG_TAB[index].address + i));}encrypt(UidArray, tempbuf, RNG_TAB[index].length, ReEncryptUidArray);        }for (i = 0; i < ENCRYPT_LEN; i++) {if (ReEncryptUidArray[i] != EncryptUidArray[i]) {return 0;}}return 1;
}

3、用户仅需调用UidCompare()即可,返回值是1表示验证成功,返回值是0表示验证失败

int main() 
{uint8_t re;re = UidCompare();if(re == 1){printf("验证成功\r\n");}else{printf("验证失败\r\n");                }while(1);
}

4、修改一个bug的地方

特别注意,当前2.26版本生成的C算法这两个写错了:

#define RNG_CONST_DATA = "11 22 33 44 55 66 77 88"   //常量值
#define RNG_TAB_t RNG_TAB = {     //使能位, 存储地址, 随机数长度{0, 0x08000000, 4},{0, 0x08000000, 4},{0, 0x08000000, 4},{0, 0x08000000, 4}
};

修改为如下即可:

uint8_t RNG_CONST_DATA[] = "11 22 33 44 55 66 77 88";   //常量值
RNG_TAB_t RNG_TAB[] = {     //使能位, 存储地址, 随机数长度{0, 0x08000000, 4},{0, 0x08000000, 4},{0, 0x08000000, 4},{0, 0x08000000, 4}
};

然后编译生成hex文件。添加到TOOL上位机进行下载:

为了方便查看验证是否正常,我们这里简单做了个串口答应,成了就提示验证成功:


5、实际验证是没问题的,完整的测试例子如下,方便大家参考:

H7-TOOL UID加密.7z (1.28MB)

这篇关于H7-TOOL脱机烧录的UID加密操作方法,支持一键生成目标板C代码,方便大家轻松操作(2024-08-20,已发布)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1098380

相关文章

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

Go Mongox轻松实现MongoDB的时间字段自动填充

《GoMongox轻松实现MongoDB的时间字段自动填充》这篇文章主要为大家详细介绍了Go语言如何使用mongox库,在插入和更新数据时自动填充时间字段,从而提升开发效率并减少重复代码,需要的可以... 目录前言时间字段填充规则Mongox 的安装使用 Mongox 进行插入操作使用 Mongox 进行更

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

Java实现状态模式的示例代码

《Java实现状态模式的示例代码》状态模式是一种行为型设计模式,允许对象根据其内部状态改变行为,本文主要介绍了Java实现状态模式的示例代码,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来... 目录一、简介1、定义2、状态模式的结构二、Java实现案例1、电灯开关状态案例2、番茄工作法状态案例

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

Python利用自带模块实现屏幕像素高效操作

《Python利用自带模块实现屏幕像素高效操作》这篇文章主要为大家详细介绍了Python如何利用自带模块实现屏幕像素高效操作,文中的示例代码讲解详,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、获取屏幕放缩比例2、获取屏幕指定坐标处像素颜色3、一个简单的使用案例4、总结1、获取屏幕放缩比例from