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

目录

一、前言

二、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/89110489

文件中的drv_common.c和drv_common.h直接替换掉原来的就行。

本项目的交流QQ群:701889554

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis--16--Spring Data Redis

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Spring Data Redishttps://spring.io/projects/spring-data-redis 1.依赖2.RedisTemplate3.案例 序列化1.默认是 JdkSerializationRedisSerializer2.添加Redis配置文…

JRT多平台初始化程序

这么多年客户端一直只做Windows&#xff0c;所以初始化程序用C#写个Exe&#xff0c;按网站生成的下载清单文件一个个下载和部署客户端环境是可以的。新的由于设计目标就是支持多平台的&#xff0c;所以需要重新考虑初始化设计。 介绍和演示视频 设计目标有以下&#xff1a; 1…

软件开发安全备受重视,浙江某运营商引入CWASP认证课程,

​浙江省某大型运营商是一家实力雄厚、服务优质的通信运营商&#xff0c;致力于为全省用户提供优质、高效的通信服务。数字时代&#xff0c;该运营商顺应信息能量融合发展趋势&#xff0c;系统打造以5G、算力网络、能力中台为重点的新型信息基础设施&#xff0c;夯实产业转型升…

idea keymap用eclipse的相关快捷键

idea快捷键用eclipse的方式 CtrlShiftR 搜索文件 shiftshift 全部文件/类搜索 CtrlH 全局搜索 CtrlO 快速打开Outline大纲视图 ctrle 查看recent窗口文件 ctrlt 快速进入接口的实现类 ctrlshiftf 格式化代码 altshiftr 变量或函数的重命名 ctrlshifto 移除无用的头文…

C/C++内存泄漏及检测

“该死系统存在内存泄漏问题”&#xff0c;项目中由于各方面因素&#xff0c;总是有人抱怨存在内存泄漏&#xff0c;系统长时间运行之后&#xff0c;可用内存越来越少&#xff0c;甚至导致了某些服务失败。内存泄漏是最难发现的常见错误之一&#xff0c;因为除非用完内存或调用…

【LeetCode】二叉树类题目详解

二叉树 二叉树的理论基础 二叉树是结点的度数之和不超过2的树&#xff0c;二叉树总共有五种基本形态 二叉树的种类主要有&#xff1a; 满二叉树完全二叉树 二叉树的存储方式 顺序存储链式存储 二叉树的遍历方式 先序遍历&#xff08;深度优先搜索&#xff09;中序遍历&…

Python单元测试pytest捕获日志输出

使用pytest进行单元测试时&#xff0c;遇到了需要测试日志输出的情况&#xff0c;查看了文档 https://docs.pytest.org/en/latest/how-to/capture-stdout-stderr.html https://docs.pytest.org/en/latest/how-to/logging.html 然后试了一下&#xff0c;捕捉logger.info可以用…

微信小程序 uniapp+vue.js医疗在线问诊挂号系统4oy17

预约挂号系统的逐渐发展&#xff0c;进一步方便了广大用户&#xff0c;使其可以更方便、快捷地预约挂号&#xff0c;并且也有效地防止号贩子“倒号”&#xff0c;使用户预约挂号更公平&#xff0c;然而现有预约挂号系统或多或少有所欠缺 小程序前端框架&#xff1a;uniapp 小程…

7、configMap

1、configMap是什么 类似与pod的配置中心&#xff0c;不会因为pod的创建销毁&#xff0c;相关配置发生改变 pod定义硬编码意味着需要有效区分⽣产环境与开发过程中的pod 定义。为了能在多个环境下复⽤pod的定义&#xff0c;需要将配置从pod定义描 述中解耦出来。 2、向容器中…

python-study-day2

pycharm注释(也可修改) 快捷键ctrl /手敲一个 " # " 这个是单行注释""" """ 左边这个三个引号可以完成多行注释 基础知识 常用的数据类型 def hello(self):print("Hello")print(type(1)) print(type("1"…

Unity Standalone File Browser,Unity打开文件选择器

Unity Standalone File Browser&#xff0c;Unity打开文件选择器 下载地址&#xff1a;GitHub链接&#xff1a; https://github.com/gkngkc/UnityStandaloneFileBrowser简单的示例代码 using SFB; using System; using System.IO; using UnityEngine; using UnityEngine.UI;…

Redis从入门到精通(十六)多级缓存(一)Caffeine、JVM进程缓存

文章目录 第6章 多级缓存6.1 什么是多级缓存&#xff1f;6.2 搭建测试项目6.2.1 项目介绍6.2.2 新增商品表6.2.3 编写商品相关代码6.2.4 启动服务并测试6.2.5 导入商品查询页面&#xff0c;配置反向代理 6.3 JVM进程缓存6.3.1 Caffeine6.3.2 实现JVM进程缓存6.3.2.1 需求分析6.…

C语言--结构体大小

基本数据类型占用的字节数分别为:char(1),short(2),int(4),long(4),long long(8),float(4),double(8)。 分析一下下面结构体占用的字节数。 struct A { int a; }; struct B { char a; int b; }; int main() { printf("sizeof(struct A)%d\n", sizeof(struct A));//测…

BI数据分析软件:行业趋势与功能特点剖析

随着数据量的爆炸性增长&#xff0c;企业对于数据的需求也日益迫切。BI数据分析软件作为帮助企业实现数据驱动决策的关键工具&#xff0c;在当前的商业环境中扮演着不可或缺的角色。本文将从行业趋势、功能特点以及适用场景等方面&#xff0c;深入剖析BI数据分析软件&#xff0…

Docker容器tomcat中文名文件404错误不一定是URIEncoding,有可能是LANG=zh_CN.UTF-8引起

使用Docker部署tomcat&#xff0c;出现中文名文件无法读取&#xff0c;访问就是404错误。在网上搜索一通&#xff0c;都说是在tomcat的配置文件server.xml中修改一下URIEncoding为utf-8就行&#xff0c;但是我怎么测试都不行。最终发现&#xff0c;是Docker启动时&#xff0c;传…

关于Excel中自动填充的功能,看这篇文章就差不多了

序言 这篇文章介绍了Excel的自动填充功能。你将学习如何在Excel 365、2021、2019、2016、2013及更低版本中填充一系列数字、日期和其他数据,创建和使用自定义列表。这篇文章还让你确保你知道关于填充柄的一切,因为你可能会惊讶于这个小选项的强大。 当时间紧迫时,每一分钟…

(二)ffmpeg 下载安装以及拉流推流示例

一、ffmpeg下载安装 官网&#xff1a;https://www.ffmpeg.org/ 源码下载地址&#xff1a;https://www.ffmpeg.org/download.html#releases 下载源码压缩包 下载完成之后解压并在该目录下打开命令窗口 安装依赖环境&#xff1a; sudo apt-get install build-essential nasm …

防火墙操作!

当小编在Linux服务器上部署好程序以后&#xff0c;但是输入URL出现下述情况&#xff0c;原来是防火墙的原因&#xff01;&#xff01; 下面是一些防火墙操作&#xff01; 为保证系统安全&#xff0c;服务器的防火墙不建议关闭&#xff01;&#xff01; 但是&#xff0c;我们可…

麒麟 V10 离线 安装 k8s 和kuboard

目录 安装文件准备 主机准备 主机配置 修改主机名&#xff08;三个节点分别执行&#xff09; 配置hosts&#xff08;所有节点&#xff09; 关闭防火墙、selinux、swap、dnsmasq(所有节点) 安装依赖包&#xff08;所有节点&#xff09; 系统参数设置(所有节点) 时间同步…

C#Winform使用扩展方法自定义富文本框(RichTextBox)字体颜色

实现效果 调用方法 rtxtLog.AppendTextColorful(richTextBox1,DateTime.Now.ToString(), Color.Red); 完整代码如下 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using Sys…