单片机学习小组
直播中

杨杰

7年用户 1128经验值
私信 关注

TEA加密算法在单片机与服务器进行网络通讯中有何作用

TEA加密算法在单片机与服务器进行网络通讯中有何作用?为什么要选择TEA加密算法呢?

回帖(1)

贺若龙

2022-1-20 11:06:52
单片机上使用TEA加密通信

环境:
主机: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.size,(uint8_t *)KEY) == 0)
{
        //解密失败
        break;
}
举报

更多回帖

×
20
完善资料,
赚取积分