• 单片机上使用TEA加密通信(转)


    源:单片机上使用TEA加密通信

    本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.

    环境:

    主机: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;  
    } 
  • 相关阅读:
    apache iceberg 1.0 发布
    grafana farowebsdk web 可观测性sdk
    minio 一些配置策略
    cube.js 支持views 模式
    grafana agent 动态配置内部机制简单说明
    parcel segmentation fault 问题以及解决方法
    使用nginx limit_except 保护暴露外网的minio 服务
    grafana phlare 试用
    新版本nexus minio 集成测试
    graylog 索引数据查询处理简单说明
  • 原文地址:https://www.cnblogs.com/LittleTiger/p/6215200.html
Copyright © 2020-2023  润新知