物联网实战--驱动篇之(五)TEA和AES加密算法

news2024/11/25 20:37:54

目录

一、前言

二、TEA算法

三、AES算法

四、加解密测试

五、安全性保障


一、前言

        物联网的安全性是经常被提及的一个点,如果你的设备之间通讯没有加密的话,那么攻击者很容易就能获取并解析出报文的协议,从而根据攻击者的需要进行设备操控和敏感信息获取。举个例子,现在有很多的WiFi插座,连接WIFI后用户就能通过手机去控制插座开关,如果设计者对安全不重视,所有报文都是明文,那么攻击者只要设局让用户连在同一个局域网WiFi,获取一些身份信息,即可自己组合相关报文对插座进行控制了,是一件比较危险的事情。

        对于设备端,处理器性能有好有差的,所以对于加密算法要根据实际情况去选配,在这里,我们主要介绍TEA和AES两种加密算法,具体的算法原理属于加密学的内容,还是挺难懂的,有兴趣可以自己深入研究,我们这里主要讲下如何封装和使用这两种加密算法。

        加解密的流程如下图所示,我们这里都是对称加密,加解密用的同一个密钥,没什么太复杂的流程。

二、TEA算法

        TEA是一个非常轻量级的加解密算法,效率高、强度好,很多游戏类有实时性要求的都是用TEA算法,QQ好像也是,它的基本介绍百科里有TEA加密算法_百度百科。对于我们使用者而言,主要有几个点注意下就行了。

1、TEA采用对称加密,数据是8字节一组,密钥是16字节一组,所以对用户层的数据有要求,数据需要8字节对齐,不够的自己补齐再输入;密码要16字节。

2、TEA算法的加密强度跟算法本身关系不大,主要还是加密轮次,建议是32轮,所以驱动库里就写死了,加解密算法轮次要对应。

        下面先展现每组的加密单元,代码如下所示:


/*		
================================================================================
描述 :  TEA加密单元
输入 : 
输出 : 
================================================================================
*/
void EncryptTEA(u32 *firstChunk, u32 *secondChunk, u32* key)
{
	u32 y = *firstChunk;
	u32 z = *secondChunk;
	u32 sum = 0;
	u32 delta = 0x9e3779b9;

	for (int i = 0; i < 32; i++)//32轮运算(需要对应下面的解密核心函数的轮数一样)
	{
		sum += delta;
		y += ((z << 4) + key[0]) ^ (z + sum) ^ ((z >> 5) + key[1]);
		z += ((y << 4) + key[2]) ^ (y + sum) ^ ((y >> 5) + key[3]);
	}

	*firstChunk = y;
	*secondChunk = z;
 }

/*		
================================================================================
描述 : TEA解密单元
输入 : 
输出 : 
================================================================================
*/
void DecryptTEA(u32 *firstChunk, u32 *secondChunk, u32* key)
{
	u32  sum = 0;
	u32  y = *firstChunk;
	u32  z = *secondChunk;
	u32  delta = 0x9e3779b9;

	sum = delta << 5; //32轮运算,所以是2的5次方;16轮运算,所以是2的4次方;8轮运算,所以是2的3次方

	for (int i = 0; i < 32; i++) //32轮运算
	{
		z -= (y << 4) + key[2] ^ y + sum ^ (y >> 5) + key[3];
		y -= (z << 4) + key[0] ^ z + sum ^ (z >> 5) + key[1];
		sum -= delta;
	}

	*firstChunk = y;
	*secondChunk = z;
}

        具体核心函数的内部原理我们就不考究了,简单的观察就是4字节+4字节数据与16字节的密码做相关运算。

        接下来看下如何调用这个核心加解密函数,具体代码如下:


/*		
================================================================================
描述 :TEA数据加密函数
输入 : buff的长度必须是8的整数倍
输出 : 
================================================================================
*/
u16 tea_encrypt_buff(u8 *buff, u16 len, u32* key)
{
	u8 *p = buff; 
	u16 i,counts;

	if(len%8!=0)
	{
		printf("Encrypt buff len err!\n");
		return 0;
	}
	counts=len/8;	
	for(i=0;i<counts;i++)
	{
		EncryptTEA((u32 *)p, (u32 *)(p + 4), key);
		p+=8;
	}
	return len;
}

/*		
================================================================================
描述 : TEA数据解密函数
输入 : buff的长度必须是8的整数倍
输出 : 
================================================================================
*/
u16 tea_decrypt_buff(u8 *buff, u16 len, u32* key)  
{
	u8 *p = buff; 
	u16 i,counts;

	if(len%8!=0)
	{
		printf("Decryp buff len err!\n");
		return 0;
	}	
	counts=len/8;	
	for(i=0;i<counts;i++)
	{
		DecryptTEA((u32 *)p, (u32 *)(p + 4), key);
		p+=8;
	}
	
	return len;
}

        这是自己封装的,主要是检测输入的数据长度有没有8字节对齐,然后调用加解密函数对每个单元的数据一次操作,由于是指针传递,所以明文和密文都是在同一个缓冲区内。

三、AES算法

        AES算法是当今使用最多的对称加密算法了,效率高、安全性好,它的实现比较复杂,我们用的是mbedtls库,把其中的AES相关部分拿出来,因为整个库对于单片机来讲着实有点大了GitHub - Mbed-TLS/mbedtls: An open source, portable, easy to use, readable and flexible TLS library, and reference implementation of the PSA Cryptography API. Releases are on a varying cadence, typically around 3 - 6 months between releases.

        AES内部还分了5中加密模式,具体看这里介绍,我们选择的是cbc模式,密码16字节,其它模式自己也可以尝试。AES五种加密模式(CBC、ECB、CTR、OCF、CFB) - 知乎

        下面具体看下驱动库封装后的程序,代码如下:


/*		
================================================================================
描述 :AES-CBC模式加密
输入 : 
输出 : 
================================================================================
*/
int aes_encrypt_buff(u8 *in_buff, u16 in_len,u8 *out_buff, u16 out_size,u8 *passwd)
{
	static mbedtls_aes_context aes_ctx;
	u16 loop_cnts=0;//循环加密次数
	u8 temp_buff[20]={0};
	u8 iv[17]={0},key[17]={0};
	loop_cnts=in_len/16;
	if(in_len%16>0)
		loop_cnts++;

	if(loop_cnts*16>out_size)
		return 0;

	if(strlen((char*)passwd)>16)
	{
		memcpy(key, passwd, 16);
	}
	else
	{
		strcpy((char*)key, (char*)passwd);
	}
	mbedtls_aes_init(&aes_ctx);
	mbedtls_aes_setkey_enc(&aes_ctx, key, 128);
	memset(iv,'0',sizeof(iv));
	for(int i=0;i<loop_cnts;i++)
	{
		if(i==loop_cnts-1 && in_len%16>0)//最后一组
		{
			memset(temp_buff, 0, sizeof(temp_buff));
			memcpy(temp_buff, &in_buff[i*16], in_len%16);//用0填充
		}
		else
		{
			memcpy(temp_buff, &in_buff[i*16], 16);
		}
		mbedtls_aes_crypt_cbc(&aes_ctx,  MBEDTLS_AES_ENCRYPT, 16, iv, temp_buff,  &out_buff[i*16]);
	}

	return loop_cnts*16;
}

/*		
================================================================================
描述 :AES-CBC模式解密
输入 : 
输出 : 
================================================================================
*/
int aes_decrypt_buff(u8 *in_buff, u16 in_len,u8 *out_buff, u16 out_size,u8 *passwd)
{
	mbedtls_aes_context aes_ctx;
	u16 loop_cnts=0;//循环加密次数
	u8 temp_buff[16]={0};
	u8 iv[16]={0},key[17]={0};
	loop_cnts=in_len/16;
	if(in_len%16>0)
		return 0;   //密文长度必须是16的整数倍

	if(loop_cnts*16>out_size)
		return 0;

	if(strlen((char*)passwd)>16)
	{
		memcpy(key, passwd, 16);
	}
	else
	{
		strcpy((char*)key, (char*)passwd);
	}
	mbedtls_aes_init(&aes_ctx);
	mbedtls_aes_setkey_dec(&aes_ctx, key, 128);
	memset(iv,'0',sizeof(iv));
	for(int i=0;i<loop_cnts;i++)
	{
		memcpy(temp_buff, &in_buff[i*16], 16);
		mbedtls_aes_crypt_cbc(&aes_ctx,  MBEDTLS_AES_DECRYPT, 16, iv, temp_buff,  &out_buff[i*16]);
	}
	return loop_cnts*16;
}

        CBC模式需要初始化向量,这里全部初始化为‘0’,核心还是调用mbedtls的库函数,代码自行阅读,接下来做一些测试,看下如何使用。

四、加解密测试

        测试环境如下所示:

        如果采用的是净化器项目的工程代码,那么user_opt.h和rtconfig.h文件参数修改下,不然RAM不够用,任务无法运行,AES算法有点吃内存,对于小身板来讲比较够呛。

        下面是测试代码,放在user_app.c文件里,代码如下:

  
  u8 in_buff[32]={"0123456789ABCDEF0123456789ABCDEF"};
  u8 out_buff[32]={0};
  u8 passwd[16]={"0123456789123456"};
  
  //TEA加解密测试
  printf("*****start tea test!\n");
  printf("000 in_buff=%s\n", in_buff); 
  tea_encrypt_buff(in_buff, 32, (u32*)passwd);//TEA加密
  printf_hex("out_buff=", in_buff, 32);//打印密文

  tea_decrypt_buff(in_buff, 32, (u32*)passwd);//TEA解密
  
  printf("111 in_buff=%s\n", in_buff);//打印解密明文  
  
  //AES加解密测试
  printf("\n*****start aes test!\n");
  printf("000 in_buff=%s\n", in_buff); 
  aes_encrypt_buff(in_buff, 32, out_buff, 32, passwd);//AES加密
  printf_hex("out_buff=", out_buff, 32);//打印密文
  
  memset(in_buff, 0, 32);//清空明文区
  aes_decrypt_buff(out_buff, 32, in_buff, 32, passwd);//AES解密
  
  printf("222 in_buff=%s\n", in_buff);   

        测试结果如下图所示,密文用16进制的方式打印,不然是乱码:

        从结果上看,加解密算法没什么问题,速度也还可以,不过AES算法对于STM32F103C8T6可能还是有点大了,芯片的RAM是20KB,单纯AES文件就要用掉10KB左右,所以对于前端小型设备,可能还是TEA算法比较合适,这个自行选择。

五、安全性保障

        现在回到物联网本身,有哪些我们可以采用加密传输呢?像购买的从机设备一般是没办法的,比如485温湿度传感器,这种厂家已经固定程序了,不会为你去做适配的,不过这一类传感器也不必要加密通讯了,因为它是有线局部传输,物理环境本身比较安全。备端的加密一般放在无线组网方面和主机与服务器通讯方面。

        首先无线组网数据容易被截获,如果内容是加密的,对方破解需要代价和时间,如果你在内容里加上时间戳等信息,可以有效防止重放攻击,以后会讲的LoRa自组网就会用到加密算法了。

        主机跟服务器方面就不用多说了,这部分如果没有加密的话很容易被攻击,因为数据一般是发往互联网的,攻击者的操作手段太多了,我们只能尽可能得做好数据加密,防止一些常规手段的攻击。

        安全性不单单是加密算法的事,更重要的是密钥的存放,如果密钥很容易就被获取了,那么跟没加密是一样的。对于单片机设备,如果有一定价值,攻击者可以通过非正常手段读取单片机内部flash的所有内容,如果你的密钥是明文写在程序内的,对方很快就能获悉了,所以一个高可靠性产品的代码写起来确实不容易,至于要如何防止,只能在后续项目实操中融入了。

代码链接:https://download.csdn.net/download/ypp240124016/89105829

本项目的交流QQ群:701889554

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

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

相关文章

运行gitHub中的vue项目,遇到三个报错解决方案

报错1&#xff1a;解决npm run serve启动报错npm ERR Missing script:"serve" 启动项目的时候用npm run serve发现报了以下的错误 npm ERR! Missing script: "serve" npm ERR! npm ERR! To see a list of scripts, run: npm ERR! npm runnpm ERR! A co…

Linux安装Oracle11g(无图形界面下的静默安装)

Oracle11g安装文档-Linux静默安装 环境准备安装数据库配置监听器创建数据库测试打开防火墙 环境准备 创建组和用户 [rootlocalhost ~]# groupadd oinstall #创建oinstall组 [rootlocalhost ~]# groupadd dba  #创建dba组 [rootlocalhost ~]# useradd -g oinstall -G dba -m…

window2003 中cmd提权到system

打开cmd&#xff0c;输入命令&#xff1a; sc Create syscm2 binPath "cmd /K start" type own type interact 注意&#xff01;等号左边是有空格然后才是引号的&#xff0c;三个等号都是&#xff0c;否则会失败 成功提示&#xff1a;[SC] CreateService 成功 然后…

Junit单元测试基础

目录 配置xml文件&#xff0c;注入依赖 常用注释 1.Test 2.BeforeAll和AfterAll 3.BeforeEach和AfterEach 4.TestMethodOrder 参数化 1.单参数 2.多参数 3.通过方法生成参数 测试用例执行管理 JUnit 是一个流行的 Java 单元测试框架&#xff0c;它为开发者提供了一…

题目 2694: 蓝桥杯2022年第十三届决赛真题-最大数字【暴力解法】

最大数字 原题链接 &#x1f970;提交结果 思路 对于每一位&#xff0c;我我们都要尽力到达 9 所以我们去遍历每一位, 如果是 9 直接跳过这一位 如果可以上调到 9 我们将这一位上调到 9 &#xff0c;并且在a 中减去对应的次数 同样的&#xff0c;如果可以下调到 9&#xff0c;我…

参数仅有0.049M!基于Mamba的医学图像分割新SOTA来了!

目前&#xff0c;基于CNN和Transformer的医学图像分割面临着许多挑战。比如CNN在长距离建模能力上存在不足&#xff0c;而Transformer则受到其二次计算复杂度的制约。 相比之下&#xff0c;Mamba的设计允许模型在保持线性计算复杂度的同时&#xff0c;仍然能够捕捉到长距离的依…

【AIGC】训练数据入库(Milvus)

之前的文章有写如何获取数据、如何补充数据&#xff0c;也有说如何对数据进行清洗、如何使用结构化数据进行训练。但好像没有说如何将训练数据“入库”。这里说的入库不是指 MySQL 数据库&#xff0c;而是指向量检索库 Milvus。 众所周知&#xff0c;人工智能多用向量数据进行…

人民网至顶科技:《开启智能新时代:2024中国AI大模型产业发展报告发布》

3月26日&#xff0c;人民网财经研究院与至顶科技联合发布《开启智能新时代&#xff1a;2024年中国AI大模型产业发展报告》。该报告针对AI大模型产业发展背景、产业发展现状、典型案例、挑战及未来趋势等方面进行了系统全面的梳理&#xff0c;为政府部门、行业从业者以及社会公众…

渗透知识贴

文章目录 基础知识同源策略 常见web漏洞SQL注入漏洞 web中间件 基础知识 同源策略 同源策略是目前所有浏览器都实行的一种安全政策。A网页设置的 Cookie&#xff0c;B网页不能打开&#xff0c;除非这两个网页同源。所谓同源&#xff0c;是指&#xff1a;协议、端口、域名相同…

蓝桥杯刷题--RDay5

清理水域--枚举 8.清理水域 - 蓝桥云课 (lanqiao.cn)https://www.lanqiao.cn/problems/2413/learning/?page1&first_category_id1&second_category_id3&tags2023 小蓝有一个n m大小的矩形水域&#xff0c;小蓝将这个水域划分为n行m列&#xff0c;行数从1…

一文详解:使用HTTPS有哪些优势?

互联网发展到今天&#xff0c;HTTP协议的明文传输会让用户存在非常大的安全隐患。试想一下&#xff0c;假如你在一个HTTP协议的网站上面购物&#xff0c;你需要在页面上输入你的银行卡号和密码&#xff0c;然后你把数据提交到服务器实现购买。假如这个环节稍有不慎&#xff0c;…

ST 意法半导体人工智能(AI)X-CUBE-AI 扩展包入门指南

引言 本用户手册指导了基于 IDE 逐步构建用于 STM32 微处理器的完整人工智能&#xff08;AI&#xff09;项目&#xff0c;自动转换预训练好的神经网络&#xff08;NN&#xff09;并集成所生成的优化库。本手册还介绍了 X-CUBE-AI 扩展包&#xff0c;该扩展包与 STM32CubeMX 工具…

分类预测 | Matlab实现CPO-LSSVM冠豪猪算法优化最小二乘支持向量机数据分类预测

分类预测 | Matlab实现CPO-LSSVM冠豪猪算法优化最小二乘支持向量机数据分类预测 目录 分类预测 | Matlab实现CPO-LSSVM冠豪猪算法优化最小二乘支持向量机数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现CPO-LSSVM冠豪猪算法优化最小二乘支持向量…

【经典算法】LeetCode 5: 最长回文子串(Java/C/Python3实现含注释说明,Medium)

目录 题目描述思路及实现方式一&#xff1a;动态规划法思路代码实现Java版本C语言版本Python3版本 复杂度分析 方式二&#xff1a;中心扩展法思路代码实现Java版本C语言版本Python3版本 复杂度分析 总结相似题目 标签(题目类型)&#xff1a;回文串、动态规划 题目描述 给定一…

OpenHarmony实战:瑞芯微RK3568移植案例

本文章是基于瑞芯微RK3568芯片的DAYU200开发板&#xff0c;进行标准系统相关功能的移植&#xff0c;主要包括产品配置添加&#xff0c;内核启动、升级&#xff0c;音频ADM化&#xff0c;Camera&#xff0c;TP&#xff0c;LCD&#xff0c;WIFI&#xff0c;BT&#xff0c;vibrato…

利用电动车进电梯检测系统识别电动车入楼行为,算法上实现的难点与方案

目前&#xff0c;我国电动自行车保有量已超过3.5亿辆。有限的充电场所难以满足日益增长的充电需求。许多人选择将电动车通过电梯带进家中充电。因此&#xff0c;火灾事故时有发生。数据显示&#xff0c;与电动车有关的起火事故占火灾总比35%。电梯空间狭小密闭&#xff0c;电动…

备战蓝桥杯(日益更新)(刷题)

备战蓝桥杯&#xff08;日益更新&#xff09;&#xff08;刷题&#xff09; 文章目录 备战蓝桥杯&#xff08;日益更新&#xff09;&#xff08;刷题&#xff09;前言&#xff1a;一、二分&#xff1a;1. acwing503 借教室&#xff1a;&#xff08;二分 差分&#xff09;2. ac…

计算机硬件组成

计算机硬件组成 基本组成核心组件连接方式与总线架构与技术特殊组件总结脑图 基本组成 CPU: 执行指令和进行数据处理内存: 存储程序和数据&#xff0c;分为RAM和ROM主板: 连接所有硬件的平台&#xff0c;传输电子信号输入设备: 如键盘、鼠标等输出设备: 如显示器、打印机等 核…

Taro框架中的H5 模板基本搭建

1.H5 模板框架的搭建 一个h5 的基本框架的搭建 基础template 阿乐/H5 Taro 的基础模板

OpenHarmony实战:轻量系统STM32F407芯片移植案例

介绍基于STM32F407IGT6芯片在拓维信息Niobe407开发板上移植OpenHarmony LiteOS-M轻量系统&#xff0c;提供交通、工业领域开发板解决方案。 移植架构采用Board与SoC分离方案&#xff0c;使用arm gcc工具链Newlib C库&#xff0c;实现了lwip、littlefs、hdf等子系统及组件的适配…