单片机上使用TEA加密通信
时间:2019-02-11
本文章向大家介绍单片机上使用TEA加密通信,主要包括单片机上使用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;}
- file_put_contents— 将一个字符串写入文件
- 跨域请求的常用方式及解释
- 洛谷P1067 多项式输出(模拟)
- php常见的判断函数
- BZOJ 1179: [Apio2009]Atm(tarjan+SPFA)
- angularjs promise详解
- svn 文件状态标记含义
- php mail函数发送html邮件不解析,linux+postfix
- POJ 1523 SPF(tarjan求割点)
- css渲染(三)颜色与背景
- file_get_contents()函数超时处理方法
- tarjan系列算法代码小结
- JQuery处理json与ajax返回JSON实例
- angularjs 表单验证
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python爬虫----(1. 基本模块)
- 七日Python之路--第十二天(Django Web 开发指南)
- 三日php之路 -- 第一天(php语言参考)
- 三日php之路 -- 第一天(初识php)
- NoSQL数据库 -- MongoDB
- 数据抓取练习
- python基础 -- 简单实现HTTP协议
- RabbitMQ 学习
- asp连接access,增删改查
- Spring 中的如何自定义事件处理(Custom Event)
- python基础 -- 自定义排序
- nginx(安装)
- Spring 中基于 AOP 的 XML操作方式
- python基础 -- 内建函数
- virtualenv 安装及使用