单片机上使用TEA加密通信

作者: 刘韶轩

这里说的加密通信和常说的防止程序被破解加密还是不一样的。后者指的是程序烧录到单片机以后,防止被竞争对手读取里面的hex文件而采取的一些手段。简单点说:防抄板。

后者指的是,通信过程中,对一些比较重要的信息进行加密,这样即便别人得到了,也不知道信息是什么意思。比如说UART通信,假设正在传输IC卡的账户,密码,余额等信息。换做五年前的我,肯定是傻不愣登的直接送过去。如果有人想获取这个信息,很容易的,几条线接过去就能读到。

TEA加密是怎么加密呢?定义和原理我就不说了,百度都能找到,万一说错了还丢人。简单说下过程:算法分两部分,一部分进行加密,一部分进行解密。

发送方先对数据进行加密,然后传输;接收方收到数据,然后解密,得到真正的信息。

小白可能会问,解密算法网上遍地都是,那第三方得到以后岂不是也能解密?

理论上是这样,但是,解密还需要一个比较重要的东西,就是:密钥。

怎么读?普通字典里一般读:mi yue(蜜月?),技术字典中被标为:mi yao

这里的密钥是一个16字节的数字,必须要有这个密钥,数据才能被解密,如果没有,暴力破解?16字节可能的组合有多少种呢...........

大致就是这么一个算法,很短小,却很有用。下面是源码:

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_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;  

}  

本文转载自 单片机爱好者