前段时间由于应用需要对产品授权进行限制,所以研究了一下有关STM32 MCU的唯一ID的资料,并最终利用它实现了我们的目标。

1、基本描述

  在STM32的全系列MCU中均有一个96位的唯一设备标识符。在ST的相关资料中,对其功能的描述有3各方面:

  • 用作序列号(例如 USB 字符串序列号或其它终端应用程序)
  • 在对内部 Flash 进行编程前将唯一 ID 与软件加密原语和协议结合使用时用作安全密钥以提高 Flash 中代码的安全性
  • 激活安全自举过程等

  在资料中对其特性的描述是:96 位的唯一设备标识符提供了一个对于任何设备和任何上下文都唯一的参考号码。用户永远不能改变这些位。96 位的唯一设备标识符也可以以单字节/半字/字等不同方式读取,然后使用自定义算法连接起来。

  想要读取唯一ID,就需要知道它的存储地址,在不同系列的MCU中地址是有差别的,我们查询了部分MCU的资料并将其总结如下:

2、获取唯一ID

  前面我们对唯一ID做了简单的描述,并且得到了其存储地址,接下来我们说以说如何得到这个ID。

  前面已经描述过唯一ID可以按字节、半字、字等方式读取。唯一ID是一个96位的信息串,所以按字读取就是3个字,按半字读取就是6个,按字节读取就是12个。本质上没有区别,在这里我们按字读取。

 /*定义STM32 MCU的类型*/
typedef enum {
STM32F0,
STM32F1,
STM32F2,
STM32F3,
STM32F4,
STM32F7,
STM32L0,
STM32L1,
STM32L4,
STM32H7,
}MCUTypedef; uint32_t idAddr[]={0x1FFFF7AC, /*STM32F0唯一ID起始地址*/
0x1FFFF7E8, /*STM32F1唯一ID起始地址*/
0x1FFF7A10, /*STM32F2唯一ID起始地址*/
0x1FFFF7AC, /*STM32F3唯一ID起始地址*/
0x1FFF7A10, /*STM32F4唯一ID起始地址*/
0x1FF0F420, /*STM32F7唯一ID起始地址*/
0x1FF80050, /*STM32L0唯一ID起始地址*/
0x1FF80050, /*STM32L1唯一ID起始地址*/
0x1FFF7590, /*STM32L4唯一ID起始地址*/
0x1FF0F420}; /*STM32H7唯一ID起始地址*/ /*获取MCU的唯一ID*/
void GetSTM32MCUID(uint32_t *id,MCUTypedef type)
{
if(id!=NULL)
{
id[]=*(uint32_t*)(idAddr[type]);
id[]=*(uint32_t*)(idAddr[type]+);
id[]=*(uint32_t*)(idAddr[type]+);
}
}

3、使用唯一ID

  我们得到唯一ID当然是为了使用它,前面在ST资料中描述了三个使用方式。我们在这里来使用它实现软件权限的限制。那么如何用唯一ID来实现软件运行权限的限制呢?我们说一说思路:

  首先,我们需要指定一个Flash地址,至于于地址空间的大小则与我们需要存储的信息有关,一般都不会太长。例如,我们使用MD5来生成加密信息,则最多需要16个字节的存储空间;如果我们使用SHA1来作为生成算法,则最多需要20个字节的空间。当然,我们也可以选取其中的一段或几段。不管选用多大的空间都需要将其清零,即初始化为0xFFFFFFFF。

  接下来在程序运行前读取前面指定的地址并读取其值,并判断是否全部为0xFFFFFFFF,即判断程序是否第一次运行。如果是,那么就获取唯一ID并作相应的处理,然后将信息写入前面指定的地址中。

  如果不是第一次运行,则读取指定地址的值,并用同样的算法处理唯一ID。然后比较存储的信息与计算的信息是否一致,一致则启动程序运行,不一致则终止运行。

  如果有人使用工具读出FLASH内容时,因为该指定的地址已经被写入了信息,所以如果把读出的文件再烧到其它MCU芯片,因唯一ID不同所以信息完全不符,程序就不会运行。从而实现了对程序权限的限制。

欢迎关注:

如何获取STM32 MCU的唯一ID的更多相关文章

  1. 如何获取STM32 MCU的唯一ID及应用(转)

    源: 如何获取STM32 MCU的唯一ID

  2. 获取单片机唯一id(stm32获取单片机唯一id)

    stm32唯一id: 不同型号的stm32单片机,id不在同一地址上!具体地址可以通过用户手册中的Device electronic signature>Unique device ID reg ...

  3. STM32全球唯一ID读取方法

    产品唯一的身份标识非常适合:● 用来作为序列号(例如USB字符序列号或者其他的终端应用)● 用来作为密码,在编写闪存时,将此唯一标识与软件加解密算法结合使用,提高代码在闪存存储器内的安全性.● 用来激 ...

  4. STM32唯一ID(Unique Device ID)的读取方法

    每一个STM32微控制器都自带一个96位的唯一ID,也就是Unique Device ID或称为UID,这个唯一ID在任何情况下都是唯一的且不允许修改.    在开发过程中,可能需要用到这个UID,比 ...

  5. Java工具类:获取long型唯一ID

    直接上代码: import java.text.SimpleDateFormat; import java.util.Date; /** * 获取long型唯一ID */ public class I ...

  6. PHP获取时间戳和微秒数以及生成唯一ID

    microtime函数 描述:返回当前Unix时间戳和微秒数 语法:mixed microtime( [ bool $get_as_float ] ) //直接输出 echo microtime(); ...

  7. 高并发分布式环境中获取全局唯一ID[分布式数据库全局唯一主键生成]

    需求说明 在过去单机系统中,生成唯一ID比较简单,可以使用MySQL的自增主键或者Oracle中的sequence, 在现在的大型高并发分布式系统中,以上策略就会有问题了,因为不同的数据库会部署到不同 ...

  8. .net core 获取树莓派的机器码,唯一ID,唯一串号

    今天在实际开发树莓派程序的时候,碰到了一个问题,需要获取到树莓派的唯一串号信息.必须在.net core的环境下: 那么如何实现呢?我们先查找树莓派的基本信息是储存在哪里的? 我们在下面的路径里找到了 ...

  9. 只要单片机具有真正唯一ID,就可以让加密坚不可摧(转)

    源:只要单片机具有真正唯一ID,就可以让加密坚不可摧 http://www.amobbs.com/thread-5518980-1-1.html 第一环:ID-->F1(ID) -----> ...

随机推荐

  1. PHP获取表单并使用数组存储 疯狂提示 Notice: Undefined offset

    $answer=array(); $answer[0]='0'; for($i=1;$i<=$QUESTION_COUNT;$i++){ $answer[$i]=$_POST[(string)$ ...

  2. MongoDB初探-基本语句和数据结构

    MySQL: 1 金老板 18 15512351234 2 小哪吒 20 15312341234 3 Alex 73 15512341234 MongoDB: { { id : 1, name:金老板 ...

  3. 怎样远程访问 MySQL

    比如我在PC上安装有 phpmyadmin, 图形界面很友好,我的MySQL 在一台Centos 7.5服务器上,很自然的想到用phpmyadmin 去登录linux上的MySQL. 但是折腾了很久也 ...

  4. 用Nodejs连接MySQL

    转载,原地址:http://blog.fens.me/nodejs-mysql-intro/ 前言 MySQL是一款常用的开源数据库产品,通常也是免费数据库的首选.查了一下NPM列表,发现Nodejs ...

  5. Spark Streaming连接Kafka的两种方式 direct 跟receiver 方式接收数据的区别

    Receiver是使用Kafka的高层次Consumer API来实现的. Receiver从Kafka中获取的数据都是存储在Spark Executor的内存中的,然后Spark Streaming ...

  6. react组件之间的组合方式

    组合方式: 1/直接嵌套的方式 2/组件以变量的形式放置 3/可以通过props值,以变量的形式相当于作为参数传递父组件,然后进行组合 import React,{Component} from 'r ...

  7. axios 在Vue全局引入的方法

    在main.js中: import axios form axios Vue.prototype.$axios = axios 组件中使用: submitFrom () { this.$axios.g ...

  8. python问题:TypeError: a bytes-like object is required, not 'str'

    源程序: import socket target_host = "www.baidu.com" # 127.0.0.1 target_port = 80 # 建立一个socket ...

  9. 微信小程序滚动Tab选项卡:左右可滑动切换

    最终效果如上.问题: 1.tab标题总共8个,所以一屏无法全部显示. 2.tab内容区左右滑动切换时,tab标题随即做标记(active). 3.当active的标题不在当前屏显示时,要使其能显示到当 ...

  10. python 导入numpy 导致多进程绑定同一个CPU问题解决方法

    python 如果有导入numpy模块的import语句,会导致默认将多进程程序的每个进程都绑定到同一个CPU core上, 失去了多进程在多核CPU上的性能优越性,这和CPU affinity(CP ...