上位机:远程解锁加密工具 v1.7.exe
下位机代码:
- #include "stm32f10x.h"
- #include "stm32f10x_usart.h"
- #include "stm32f10x_iwdg.h"
- #include "GPIO.H"//要使用GPIO中间件的话记得包含头文件
- #include "USART.H"
- #include "NVIC.H"
- #include "IWDG.H"
- #include "AES.h"
- #include "stdio.h"
- #include "stdlib.h"
- #include <string.h>
- #include "core_cm3.h"
- void STM32_USART_RX_interrupt(void);
- #define LED0 PCout(13)// PB5
- //初始化PB5和PE5为输出口.并使能这两个口的时钟
- //LED IO初始化
- void LED_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能PB,PE端口时钟
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //LED0-->PB.5 端口配置
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
- GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
- }
- /******************************************************************************
- 函数名称:读取芯片唯一ID码
- 备 注:
- ******************************************************************************/
- unsigned char BFLASH[12]; //存放芯片ID的临时变量
- void Get_ChipID(void)
- {
- u32 temp0, temp1, temp2;
- temp0 = *(__IO u32 *)(0x1FFFF7E8); //产品唯一身份标识寄存器(96位)
- temp1 = *(__IO u32 *)(0x1FFFF7EC);
- temp2 = *(__IO u32 *)(0x1FFFF7F0);
- //ID码地址: 0x1FFFF7E8 0x1FFFF7EC 0x1FFFF7F0 ,只需要读取这个地址中的数据就可以了。
- BFLASH[0] = (u8)(temp0 & 0x000000FF);
- BFLASH[1] = (u8)((temp0 & 0x0000FF00) >> 8);
- BFLASH[2] = (u8)((temp0 & 0x00FF0000) >> 16);
- BFLASH[3] = (u8)((temp0 & 0xFF000000) >> 24);
- BFLASH[4] = (u8)(temp1 & 0x000000FF);
- BFLASH[5] = (u8)((temp1 & 0x0000FF00) >> 8);
- BFLASH[6] = (u8)((temp1 & 0x00FF0000) >> 16);
- BFLASH[7] = (u8)((temp1 & 0xFF000000) >> 24);
- BFLASH[8] = (u8)(temp2 & 0x000000FF);
- BFLASH[9] = (u8)((temp2 & 0x0000FF00) >> 8);
- BFLASH[10] = (u8)((temp2 & 0x00FF0000) >> 16);
- BFLASH[11] = (u8)((temp2 & 0xFF000000) >> 24);
- }
- void SoftReset(void)
- {
- __set_FAULTMASK(1); // 关闭所有中端
- NVIC_SystemReset();// 复位
- }
- void Delay(unsigned int i)
- {
- unsigned int j;
- for(; i > 0; i--)
- for(j = 0; j < 1000; j++);
- }
- #define STM32CLI() __set_PRIMASK(1) //关闭总中断
- #define STM32SEI() __set_PRIMASK(0) //开放总中断
- void STM32_USART_RX_interrupt(void)
- {
- u8 i, data[42];
- char hex[128];
- char *p_hex = hex;
- char aesKey[16];//加解密的密钥,注意:此算法只适用于AES16位密钥加解密,不适用于32位密钥加解密
- //该AES算法加密方式为:AES-128bit/ECB/PKCS5Padding
- char expressText[64]; //存放待加密的明文数据,具体缓存大小根据用户待加密数据长度自己任意修改
- char cipherText[64];//存放已加密的密文数据,具体缓存大小根据用户解密后的数据长度自己任意修改
- char unLockDT[3];//解锁日期(当日有效)
- char LockDT[3];//锁定日期()
- char MachID[12];//机器码
- char AdminTEL[5];//管理者手机号
- if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) == SET) //溢出
- {
- USART_ClearFlag(USART1, USART_FLAG_ORE); //读SR
- USART_ReceiveData(USART1); //读DR
- }
- if (USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET)
- {
- USART_ReceiveData(USART1);
- USART_ClearFlag(USART1, USART_FLAG_PE);
- }
- if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
- {
- USART_ReceiveData(USART1);
- USART_ClearFlag(USART1, USART_FLAG_ORE);
- }
- if (USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET)
- {
- USART_ReceiveData(USART1);
- USART_ClearFlag(USART1, USART_FLAG_FE);
- }
- //*
- for (i = 0; i < 42; i++)
- {
- data[i] = DK_USART_WAIT_RXBYTE(1); //读取接收到的数据
- }
- //*/
- /*
- 指令格式:
- 同步字2+序号1+密钥32+解锁日期3+客户机器码24+锁定日期3+管理者手机号20=85位
- */
- //*
- if ((data[0] == 0xF3) & (data[1] == 0x3A)) //同步字正确
- {
- switch (data[2]) //第1字节
- {
- case 0x01://取密钥
- {
- //*
- //-----------------------------------------------------------------
- memset(aesKey , 0 , 16);//清零
- for (i = 0; i < 16; i++)
- {
- aesKey[i] = data[i + 3]; //得到密钥
- }
- //-----------------------------------------------------------------
- memset(unLockDT , 0 , 3);//清零
- for (i = 0; i < 3; i++)
- {
- unLockDT[i] = data[i + 19]; //解锁日期(当日有效)
- }
- //-----------------------------------------------------------------
- memset(MachID , 0 , 12);//清零
- for (i = 0; i < 12; i++)
- {
- MachID[i] = data[i + 22]; //机器码
- }
- //-----------------------------------------------------------------
- memset(LockDT , 0 , 3);//清零
- for (i = 0; i < 3; i++)
- {
- LockDT[i] = data[i + 34]; //锁定日期()
- }
- //-----------------------------------------------------------------
- memset(AdminTEL , 0 , 5);//清零
- for (i = 0; i < 5; i++)
- {
- AdminTEL[i] = data[i + 37]; //管理者手机号
- }
- //-----------------------------------------------------------------
- //------------------------------------------------------------------------
- //*加密过程:测试通过
- memset(expressText , 0 , 64);
- memset(cipherText , 0 , 64);
- //------------------------------------------------------------------------
- for (i = 0; i < 39; i++)
- {
- expressText[i] = data[i + 3]; //
- }
- BFH_Encrypt(expressText , cipherText , aesKey); //使用密钥aesKey把expressText加密为cipherText
- StrToHex(cipherText, p_hex);//把cipherText转换为16进制字符串hex
- //------------------------------------------------------------------------
- DK_USART_PUTS(DK_USART1, hex);//返回加密数据
- //DK_USART_PUTS(DK_USART1, "\r\n");
- //------------------------------------------------------------------------
- //------------------------------------------------------------------------
- /*解密过程:测试通过
- memset(expressText , 0 , 64);
- memset(cipherText , 0 , 64);
- //等待解密的字符串不完整将不会解密成功
- u8 *ihex;//使用指针,可以动态赋值
- ihex = "7677685A504563592B54503047644E417564502B6530714C4B523771746B5650435233725142344E446477417678476B5541536F71723376682F49636555692B";
- HexToStr(ihex, cipherText);//ihex值为16进制字符串,需要先转换成普通字符串再进行解密
- BFH_Decrypt(expressText , cipherText , aesKey);//使用密钥aesKey把cipherText解密为expressText
- StrToHex(expressText, p_hex);//把expressText转换为16进制字符串hex
- //------------------------------------------------------------------------
- u8 IDBlock[25];
- memset(IDBlock , 0 , 25);
- StrCopy(IDBlock, hex, 32, 6);//解锁日期
- DK_USART_PUTS(DK_USART1, "解锁日期=");
- DK_USART_PUTS(DK_USART1, IDBlock);
- DK_USART_PUTS(DK_USART1, "\r\n");
- memset(IDBlock , 0 , 25);
- StrCopy(IDBlock, hex, 38, 24);//机器码
- DK_USART_PUTS(DK_USART1, "机器码=");
- DK_USART_PUTS(DK_USART1, IDBlock);
- DK_USART_PUTS(DK_USART1, "\r\n");
- memset(IDBlock , 0 , 25);
- StrCopy(IDBlock, hex, 62, 6);//锁定日期
- DK_USART_PUTS(DK_USART1, "锁定日期=");
- DK_USART_PUTS(DK_USART1, IDBlock);
- DK_USART_PUTS(DK_USART1, "\r\n");
- memset(IDBlock , 0 , 25);
- StrCopy(IDBlock, hex, 68, 20);//管理者手机号
- DK_USART_PUTS(DK_USART1, "管理者手机号=");
- DK_USART_PUTS(DK_USART1, IDBlock);
- DK_USART_PUTS(DK_USART1, "\r\n");
- //-----------------------------------------------------------
- //*/
- /*解密过程:测试通过*/
- /*
- memset(expressText , 0 , 64);
- memset(cipherText , 0 , 64);
- // memcpy(aesKey , "48FF6A06756754483041126720170926" , 16); //AES加密密钥,16字节(128bit)
- /*等解密的字符串不完整将不会解密成功*/
- /*
- char *ihex;//使用指针,可以动态赋值
- ihex = "48FF6A06756754483041126720170926";
- HexToStr(ihex, aesKey);//ihex值为16进制字符串,需要先转换成普通字符串作为密钥
- ihex = "7677685A504563592B54503047644E417564502B6530714C4B523771746B5650435233725142344E446477417678476B5541536F71723376682F49636555692B";
- HexToStr(ihex, cipherText);//ihex值为16进制字符串,需要先转换成普通字符串再进行解密
- BFH_Decrypt(expressText , cipherText , aesKey);//使用密钥aesKey把cipherText解密为expressText
- //------------------------------------------------------------------------
- memset(unLockDT , 0 , 3);
- StrCopy(unLockDT, expressText, 16, 3);//解锁日期(当日有效)
- memset(MachID , 0 , 12);
- StrCopy(MachID, expressText, 19, 12);//机器码
- memset(LockDT , 0 , 3);
- StrCopy(LockDT, expressText, 31, 3);//锁定日期
- memset(AdminTEL , 0 , 5);
- StrCopy(AdminTEL, expressText, 34, 5);//管理者手机号
- //CAN_Return(0x31, HDID, AdminTEL[0], AdminTEL[1], AdminTEL[2], AdminTEL[3], AdminTEL[4], 0xDD);
- //下面是对解密后的明文expressText解析内容:
- //0-5:解锁有效日期、6-29:机器码、30-36:再次锁定日期
- /*
- 1、机器码是否正确
- 2、检测解锁有效日期、锁定日期是否有效
- 3、再次锁定有效期。
- */
- //-------------------------------------
- /*
- u8 Fixed = 0;
- u8 AdminMem[5] = {0x39, 0x78, 0x82, 0x80, 0x80};
- u16 TBS = 0;
- LED0 = 0;
- for (i = 0; i < 4; i++)
- {
- if (AdminTEL[i] != AdminMem[i])
- {
- Fixed = 1;
- break;
- }
- }
- if (!Fixed)//解锁手机号正确
- {
- for (i = 0; i < 11; i++)
- {
- if (MachID[i] != BFLASH[i])
- {
- Fixed = 1;
- break;
- }
- }
- if (!Fixed)//ID正确
- {
- if (TBS == 1709)//解锁日期有效
- {
- if (TBS == 1712)//锁定日期有效
- {
- //执行锁定日期更新
- LED0 = 1;
- }
- }
- }
- }
- */
- break;
- }
- }
- }
- //*/
- }
- int main(void)//利用库函数来实现
- {
- SystemInit();
- DK_USART_Init(115200, 1); //初始化USART1
- DK_NVIC_Init(1);//选择NVIC_PriorityGroup_4,4位全部为占先式优先级,要实现中断必须先初始化NVIC
- DK_NVIC_IRQ_Set(USART1_IRQn, 0, 0, ENABLE); //要实现外设中断,必须先设置外设的优先级
- DK_USART_OPen_INT(1);//打开USART1的接收中断,然后再打开外设的中断功能
- LED_Init(); //LED端口初始化
- while(1)
- {
- Delay(10000);
- LED0 = !LED0;
- }
- }
复制代码
单片机代码与上位机exe文件下载:
STM32F103配合Win上位机实现加解密(类似U盾原理).7z
(377.68 KB, 下载次数: 0)
|