目录
概要
每个芯片都有唯一的UID,根据用户手册的存储器架构可以快速找到UID的存放地址,以PY32F403为例,UID存放在0x1FFFF5800
在用户手册可以快速找到
实现原理是自己写一套加密算法,读出UID,进行加密处理生成密文。生成密文后将密文保存到非易失存储器中,可以是板上存储器,也可以是FLASH。官方推荐的做法是存放到备份寄存器中,备份寄存器自带侵入检测,可以保护数据。
执行一遍加密程序后就可以烧录APP,APP运行时解密密文,将解密后的密文与UID对比,根据自己设计的逻辑判断是否正确,如果错误就清除程序。这样即使不法商家得到了APP,没有加密程序也无法运行。具体原理就是这样,接下来是代码实现
整体架构流程
1、FLASH相关操作
读指定地址数据
//读半字
static inline uint16_t FLASH_Read_HalfWord(uint32_t addr)
{
return *(__IO uint16_t *)addr;
}
//读n个半字
void FLASH_Read(uint32_t addr,uint16_t *data,uint16_t data_len)
{
for(int i = 0; i < data_len; i++)
{
*(data+i) = FLASH_Read_HalfWord(addr);
//两字节偏移
addr += 2;
}
}
整片擦除
//擦除片
void FLASH_Erase_Mass(uint32_t addr)
{
HAL_FLASH_Unlock();
FLASH_EraseInitTypeDef pEraseInit = {
.TypeErase = FLASH_TYPEERASE_MASSERASE,
};
uint32_t MassError;
HAL_FLASH_Erase(&pEraseInit,&MassError);
HAL_FLASH_Lock();
}
2、加密程序
读UID的代码最好放在开头,我的芯片调用完HAL_RCC_ClockConfig(&ClkInitstruct, FLASH_LATENCY_5)后Informatin block空间的数据就无法访问了
FLASH_Read(UID_ADDR,(uint16_t *)uid,6);
一个简单的加密算法,移位后异或B4,B4就作为密钥在解密程序中使用,加密后将密文写入EEPROM
void MU_Encrypt(void)
{
//加密
int i = 0;
uint8_t swan_data;
for(i = 0; i < 12; i++)
{
swan_data = uid[i] & 0x18;
uid[i] = uid[i]<<5 | uid[i]>>5;
uid[i] |= swan_data;
uid[i] ^= 0xB4;
}
//写入EEPROM
MU_HK_Write_Byte(0x60,uid[0]);
MU_HK_Write_Byte(0x61,uid[1]);
MU_HK_Write_Byte(0x62,uid[2]);
MU_HK_Write_Byte(0x63,uid[3]);
MU_HK_Write_Byte(0x64,uid[4]);
MU_HK_Write_Byte(0x65,uid[5]);
MU_HK_Write_Byte(0x66,uid[6]);
MU_HK_Write_Byte(0x67,uid[7]);
MU_HK_Write_Byte(0x68,uid[8]);
MU_HK_Write_Byte(0x69,uid[9]);
MU_HK_Write_Byte(0x6A,uid[10]);
MU_HK_Write_Byte(0x6B,uid[11]);
}
3、解密程序
很简单,只要异或和移位的顺序不要搞反就行。如果有一位对不上就擦除整片FLASH
//读取加密序列号并解密
void MU_Decrypt(void)
{
uint8_t decrypt[12] = {0};
decrypt[0] = MU_HK_Read_Byte(0x60);
decrypt[1] = MU_HK_Read_Byte(0x61);
decrypt[2] = MU_HK_Read_Byte(0x62);
decrypt[3] = MU_HK_Read_Byte(0x63);
decrypt[4] = MU_HK_Read_Byte(0x64);
decrypt[5] = MU_HK_Read_Byte(0x65);
decrypt[6] = MU_HK_Read_Byte(0x66);
decrypt[7] = MU_HK_Read_Byte(0x67);
decrypt[8] = MU_HK_Read_Byte(0x68);
decrypt[9] = MU_HK_Read_Byte(0x69);
decrypt[10] = MU_HK_Read_Byte(0x6A);
decrypt[11] = MU_HK_Read_Byte(0x6B);
//解密
uint8_t swan_data;
for(int i = 0; i < 12; i++)
{
decrypt[i] ^= 0xB4;
swan_data = decrypt[i] & 0x18;
decrypt[i] = decrypt[i]<<5 | decrypt[i]>>5;
decrypt[i] |= swan_data;
}
for(int i = 0; i < 12; i++)
{
if(decrypt[i] != uid[i])
{
APP_DISTORY;
}
}
}
小结
可以在此基础上加强保护,例如将密文分段存储到不同的空间,使用多个密钥进行加密,使用多个加密程序生成多个密文......
标签:加密,UID,芯片,decrypt,MU,HK,Read,Byte,uid From: https://blog.csdn.net/weixin_63723467/article/details/144839384