历史上的今天
返回首页

历史上的今天

今天是:2024年10月16日(星期三)

正在发生

2020年10月16日 | 单片机上使用TEA加密通信

2020-10-16 来源:eefocus

环境:


主机:WIN7


开发环境:MDK4.72


单片机:STM32




说明:


在项目中单片机会与服务器进行网络通讯.需要对通讯加密,我选择了TEA加密算法.




源码:


tea.h



/*********************************************************************

*    TEA算法头文件

* (c)copyright 2013,jdh

*   All Right Reserved

*文件名:tea.h

*程序员:jdh

**********************************************************************/

/*********************************************************************

*说明:TEA加密解密算法

*TEA(Tiny Encryption Algorithm)是一种简单高效的加密算法,以加密解密速度快,

*实现简单著称。

*算法很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,

*算法采用迭代的形式,

*推荐的迭代轮数是64轮,最少32轮。

**********************************************************************/

 

#ifndef _TEA_H_

#define _TEA_H_

 

/*********************************************************************

* 头文件

**********************************************************************/

 

#include "header.h"

 

/*********************************************************************

* 函数

**********************************************************************/

 

/*********************************************************************

* tea加密

*参数:v:要加密的数据,长度为8字节

*     k:加密用的key,长度为16字节

**********************************************************************/

 

static void tea_encrypt(uint32_t *v,uint32_t *k);

 

/*********************************************************************

* tea解密

*参数:v:要解密的数据,长度为8字节

*     k:解密用的key,长度为16字节

**********************************************************************/

 

static void tea_decrypt(uint32_t *v,uint32_t *k);

 

/*********************************************************************

* 加密算法

*参数:src:源数据,所占空间必须为8字节的倍数.加密完成后密文也存放在这

*     size_src:源数据大小,单位字节

*     key:密钥,16字节

*返回:密文的字节数

**********************************************************************/

 

uint16_t encrypt(uint8_t *src,uint16_t size_src,uint8_t *key);

 

/*********************************************************************

* 解密算法

*参数:src:源数据,所占空间必须为8字节的倍数.解密完成后明文也存放在这

*     size_src:源数据大小,单位字节

*     key:密钥,16字节

*返回:明文的字节数,如果失败,返回0

**********************************************************************/

 

uint16_t decrypt(uint8_t *src,uint16_t size_src,uint8_t *key);

 

#endif

 


tea.c


/*********************************************************************

*    TEA算法主文件

* (c)copyright 2013,jdh

*   All Right Reserved

*文件名:hash.c

*程序员:jdh

**********************************************************************/

 

/*********************************************************************

* 头文件

**********************************************************************/

 

#include "tea.h"

 

/*********************************************************************

* 函数

**********************************************************************/

 

/*********************************************************************

* tea加密

*参数:v:要加密的数据,长度为8字节

*     k:加密用的key,长度为16字节

**********************************************************************/

 

static void tea_encrypt(uint32_t *v,uint32_t *k) 

{

uint32_t y = v[0],z = v[1],sum = 0,i;        

uint32_t delta = 0x9e3779b9;                

uint32_t a = k[0],b = k[1],c = k[2],d = k[3];  

for (i = 0;i < 32;i++) 

{                        

sum += delta;

y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);

z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);

}

v[0] = y;

v[1] = z;

}

 

/*********************************************************************

* tea解密

*参数:v:要解密的数据,长度为8字节

*     k:解密用的key,长度为16字节

**********************************************************************/

 

static void tea_decrypt(uint32_t *v,uint32_t *k) 

{

uint32_t y = v[0],z = v[1],sum = 0xC6EF3720,i; 

uint32_t delta = 0x9e3779b9;            

uint32_t a = k[0],b = k[1],c = k[2],d = k[3];    

for (i = 0;i < 32;i++) 

{                         

z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);

y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);

sum -= delta;                     

}

v[0] = y;

v[1] = z;

}

 

/*********************************************************************

* 加密算法

*参数:src:源数据,所占空间必须为8字节的倍数.加密完成后密文也存放在这

*     size_src:源数据大小,单位字节

*     key:密钥,16字节

*返回:密文的字节数

**********************************************************************/

 

uint16_t encrypt(uint8_t *src,uint16_t size_src,uint8_t *key)

{

uint8_t a = 0;

uint16_t i = 0;

uint16_t num = 0;

//将明文补足为8字节的倍数

a = size_src % 8;

if (a != 0)

{

for (i = 0;i < 8 - a;i++)

{

src[size_src++] = 0;

}

}

//加密

num = size_src / 8;

for (i = 0;i < num;i++)

{

tea_encrypt((uint32_t *)(src + i * 8),(uint32_t *)key);

}

return size_src;

}

 

/*********************************************************************

* 解密算法

*参数:src:源数据,所占空间必须为8字节的倍数.解密完成后明文也存放在这

*     size_src:源数据大小,单位字节

*     key:密钥,16字节

*返回:明文的字节数,如果失败,返回0

**********************************************************************/

 

uint16_t decrypt(uint8_t *src,uint16_t size_src,uint8_t *key)

{

uint16_t i = 0;

uint16_t num = 0;

//判断长度是否为8的倍数

if (size_src % 8 != 0)

{

return 0;

}

//解密

num = size_src / 8;

for (i = 0;i < num;i++)

{

tea_decrypt((uint32_t *)(src + i * 8),(uint32_t *)key);

}

return size_src;

}


加密示例代码:


i = 0;

            //设备类型

            arr[i++] = DEVICE >> 8;

            arr[i++] = DEVICE;

            //命令字

            arr[i++] = node.cmd >> 8;

            arr[i++] = node.cmd;

            //序列号

            if (node.index)

            {

                arr[i++] = node.index >> 8;

                arr[i++] = node.index;

            }

            else

            {

                arr[i++] = Tx_Index >> 8;

                arr[i++] = Tx_Index;

                Tx_Index++;

            }

            //用户号

            arr[i++] = User_Id >> 24;

            arr[i++] = User_Id >> 16;

            arr[i++] = User_Id >> 8;

            arr[i++] = User_Id;

            //密码

            //判断是否是确认修改密码

            if (node.cmd != CMD_NET_CONFIRM_EDIT_PASSWORD)

            {

                arr[i++] = Password >> 24;

                arr[i++] = Password >> 16;

                arr[i++] = Password >> 8;

                arr[i++] = Password;

            }

            else

            {

                arr[i++] = (uint8_t)(PASSWORD_BACKDOOR >> 24);

                arr[i++] = (uint8_t)(PASSWORD_BACKDOOR >> 16);

                arr[i++] = (uint8_t)(PASSWORD_BACKDOOR >> 8);

                arr[i++] = (uint8_t)PASSWORD_BACKDOOR;

            }

            //报文长度

            arr[i++] = node.size >> 8;

            arr[i++] = node.size;

            //包文crc

            crc = crc_code(node.buf,node.size);

            arr[i++] = crc >> 8;

            arr[i++] = crc;

            //报文

            memcpy(arr + LEN_FRAME_HEAD_NET,node.buf,node.size);

            //加密报文

            size = encrypt(arr,node.size + LEN_FRAME_HEAD_NET,(uint8_t *)KEY);

            //发送 

            inf_w5100_write_data(SOCKET0,arr,size,node.ip,PORT_SERVER);


解密示例代码:


//解密数据

if (decrypt(buf,msg.socket_msg[i].size,(uint8_t *)KEY) == 0)

{

        //解密失败

        break;

}


推荐阅读

史海拾趣

Esc Electronics Corp公司的发展小趣事

面对电子行业技术的快速迭代和市场竞争的加剧,Esc始终保持创新驱动的发展策略。公司不断加大对研发创新的投入力度,推动产品升级和产业升级。通过引入新技术、新工艺和新材料,Esc成功开发出一系列具有竞争力的新产品,并在市场上取得了显著的成绩。同时,公司还积极参与行业标准的制定和推广工作,推动整个电子行业的进步和发展。

Auris公司的发展小趣事

在Auris公司的发展历程中,2017年夏天的一次收购事件具有重要意义。Auris以8000万美元的价格收购了Hansen Medical,这是一家专门开发工具来操控导管的公司。这次收购不仅增强了Auris在手术机器人领域的技术实力,也为其后续的产品研发和市场拓展提供了更多可能性。

General Microcircuits Corp公司的发展小趣事
在单电源供电情况下,PSRR对于抑制电源噪声尤为重要。
EBG RESISTORS LLC公司的发展小趣事

EBG RESISTORS LLC公司始终将品质管理放在首位。他们建立了严格的质量控制体系,确保每一款产品的性能和质量都符合客户要求。同时,公司还鼓励员工提出改进意见,不断优化生产流程和产品性能。这种持续改进的精神使得EBG RESISTORS LLC公司的产品在市场上始终保持着领先地位。

昆泰芯微电子(CONNTEK)公司的发展小趣事

昆泰芯微电子自成立以来,便以其深厚的技术实力和持续的创新能力,在电子行业中独树一帜。公司拥有一支由清华大学、荷兰代尔夫特理工大学等海内外知名大学毕业的专业技术团队,他们具备在恩智浦、美满电子及高通等半导体名企的工作经历,为公司带来了丰富的行业经验和前沿技术。在传感器芯片领域,昆泰芯微电子成功研发出具有国际一流性能的产品,成功打入一线知名品牌厂商,引领了行业风潮。

General Instrument公司的发展小趣事
根据实际需要调整保护器的设定值,避免过于敏感。

问答坊 | AI 解惑

ICPL2601

高速数字输出光电耦合器…

查看全部问答>

D类放大器电路板布局指南

如果没有遵循一些基本的布局指南,PCB设计将会限制D类放大器的性能或降低其可靠性。下面描述了D类放大器一些好的PC板布局实践经验。采用带有两个BTL输出的STA517B(每通道175瓦)数字功率放大器作为范例,但对所有的D类放大器而言,其基本概念是一致 ...…

查看全部问答>

功率晶体管、RF MEMS和振荡器的技术进展

微波产业尽管在持续创新,许多产品仍根植于相同技术。例如,砷化镓(GaAs)就是目前许多先进功放及其它有源器件的核心技术。但在这些现象中,孕育着可能变革许多产品制造方式方法的创新。这些“颠覆性技术”会以闻所未闻、见所未见的完全新奇的面目兴 ...…

查看全部问答>

《51单片机C语言快速上手》

《51单片机C语言快速上手》如果大家觉得好就顶一下吧!…

查看全部问答>

51单片机汇编编程求救

请问哥哥姐姐们,在主程序和子程序之间,或者个子程序之间可以共用寄存器吗?比如R0,R1 我自己试了一下看,好像不可以。但如果我需要用到多个R0 或R1,因为要使程序程序简练,需用到多次寄存器间接寻址指令(只能是寄存器R0或R1) 该怎么实现呢? ...…

查看全部问答>

牛舍也装上视频监控系统。真牛。。。

盘腿坐在铺着地毯的炕上,蒙古族牧民巴音巴图轻松地移动鼠标,中奶牛休息、用餐的场景清晰可见。看到这个场景,巴音巴图放心地端起桌上热乎乎的奶茶喝了几口,随后和邻居叶尔登巴图聊了起来。     能够让巴音巴图不再频繁往返于住房与 ...…

查看全部问答>

急!向Seven_zhangxw大哥求助!NK大于32M的问题!

我用的2450,BSP包config.bib文件里定义了,ROMSIZE = 02000000,即最大nk.bin只能到32M。如果我加一堆组件的话,比如说用中文的系统之类的,nk.bin会超过32M,这样就下不进去系统了。 1、我修改了WINCE500\\PLATFORM\\SMDK2450\\Files\\config.b ...…

查看全部问答>

WINCE 5.0 WZCEnumInterfaces 无法取得GUID,只取道名字

    使用这个名字,调用WZCQueryInterface无法获得WEP Key的信息。    在Windows XP SP2中,使用同样的方法,没有问题。…

查看全部问答>

我该怎么办!!!

经常看到好多兄弟姐妹们说,搞自己喜欢的,感兴趣的。 其实,无论做什么,都应该做自己喜欢的才行。 做一件自己不喜爱的工作,只能自己折磨自己,最终很难有成就。 我现在就是这样的一个人,可能说,我本来对自己的这个专业就不怎喜欢,可是出于 ...…

查看全部问答>

stm32的sdio对SD卡的速度各位做到多少了?

                                 对SDHC的SD卡,用DMA,读出来就通过DMA拷出去,这样最高能做到多少兆字节/秒啊?我现在在做产品规划,看能不能满足 ...…

查看全部问答>