本篇博文最后修改时间:2017年03月29日,20:32。
一、简介
本文以SimpleBLEPeripheral工程为例,介绍如何使用协议栈的数据加密与解密功能,其中秘钥为MAC经过一定算法而形成。
二、实验平台
协议栈版本:BLE-CC254x-1.4.0
编译软件:IAR 8.20.2
硬件平台:Smart RF开发板(主芯片CC2541)
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.NET/feilusia
联系方式:897503845@qq.com
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
香瓜单片机之职场交流群:450154342
五、基础知识
1、为什么需要加密与解密?
答:蓝牙数据是可以通过空中抓包而被抓取到的,因此需要将通信数据进行加密,这样别人即使知道了加密后的数据,也无法利用该数据。
2、加密与解密的过程是如何?
答:
加密过程:需要加密的数据A与秘钥KEY进行一定的算法,获得加密过的数据B。
解密过程:加密过的数据B与秘钥KEY进行一定的逆运算算法,获得加密前的数据A。
3、为什么要用MAC来形成秘钥?
答:这样可以使得每台设备的通信秘钥唯一而各不相同,使得设备安全性更强。
4、实际项目中的加密与解密流程是如何的?
答:
举例(CC2541将温度值放在广播数据中发送给手机app):
1)CC2541使用mac形成AES秘钥。
2)CC2541将温度值利用AES秘钥进行加密。
3)CC2541将加密后的温度值动态广播出来。
4)手机app使用mac形成AES秘钥。
5)手机app获取CC2541的广播数据,并解析出温度数据字段。
6)将加密后的温度值利用AES秘钥进行解密。
如上,手机app即可从CC2541获得温度值,而蓝牙传输过程中全程加密,保证了数据安全性。
六、实验步骤
1、编写并添加自定义的驱动
1)写一个驱动GUA_AES.c(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)
//******************************************************************************
//name: GUA_AES.c
//introduce: 香瓜的AES驱动
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group: 香瓜BLE之CC2541(127442605)
//changetime: 2017.03.29
//******************************************************************************
#include <ioCC2540.h>
#include "LL.h"
#include "GUA_AES.h"
/*********************内部变量************************/
static GUA_U8 sbGUA_AES_Key[16] = {0}; //AES的秘钥
/*********************内部函数************************/
static void GUA_Get_LocalMac(GUA_U8 *pGUA_LocalMac);
static void GUA_AES_GetKey(GUA_U8 *pGUA_AES_LocalMac, GUA_U8 *pGUA_AES_Key);
//******************************************************************************
//name: GUA_Get_LocalMac
//introduce: 获取本机mac
//parameter: pGUA_LocalMac:mac需要保存到的位置,需要6个字节大小
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group: 香瓜BLE之CC2541(127442605)
//changetime: 2017.03.29
//******************************************************************************
static void GUA_Get_LocalMac(GUA_U8 *pGUA_LocalMac)
{
pGUA_LocalMac[5] = *(GUA_U8 *)(0x780E); //直接指向指针内容
pGUA_LocalMac[4] = *(GUA_U8 *)(0x780F);
pGUA_LocalMac[3] = *(GUA_U8 *)(0x7810);
pGUA_LocalMac[2] = XREG(0x7811); //define函数直接读出数据
pGUA_LocalMac[1] = XREG(0x7812);
pGUA_LocalMac[0] = XREG(0x7813);
}
//******************************************************************************
//name: GUA_AES_GetKey
//introduce: 通过mac形成自定义秘钥
//parameter: pGUA_AES_LocalMac:mac地址
// pGUA_AES_Key:秘钥存放位置,需要16字节大小
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group: 香瓜BLE之CC2541(127442605)
//changetime: 2017.03.29
//******************************************************************************
static void GUA_AES_GetKey(GUA_U8 *pGUA_AES_LocalMac, GUA_U8 *pGUA_AES_Key)
{
pGUA_AES_Key[0] = 'G';
pGUA_AES_Key[1] = 'U';
pGUA_AES_Key[2] = 'A';
pGUA_AES_Key[3] = '#';
pGUA_AES_Key[4] = pGUA_AES_LocalMac[0];
pGUA_AES_Key[5] = pGUA_AES_LocalMac[1];
pGUA_AES_Key[6] = pGUA_AES_LocalMac[2];
pGUA_AES_Key[7] = pGUA_AES_LocalMac[3];
pGUA_AES_Key[8] = pGUA_AES_LocalMac[4];
pGUA_AES_Key[9] = pGUA_AES_LocalMac[5];
pGUA_AES_Key[10] = pGUA_AES_LocalMac[0] + pGUA_AES_LocalMac[1];
pGUA_AES_Key[11] = pGUA_AES_LocalMac[2] + pGUA_AES_LocalMac[3];
pGUA_AES_Key[12] = pGUA_AES_LocalMac[4] + pGUA_AES_LocalMac[5];
pGUA_AES_Key[13] = pGUA_AES_LocalMac[0] - pGUA_AES_LocalMac[1];
pGUA_AES_Key[14] = pGUA_AES_LocalMac[2] - pGUA_AES_LocalMac[3];
pGUA_AES_Key[15] = pGUA_AES_LocalMac[4] - pGUA_AES_LocalMac[5];
}
//******************************************************************************
//name: GUA_AES_Encrypted
//introduce: 加密16字节的数据
//parameter: pGUA_AES_Data:要加密的数据缓存区,必须16字节
// pGUA_AES_EncryptedData:加密后的数据缓存区,必须16字节
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group: 香瓜BLE之CC2541(127442605)
//changetime: 2017.03.29
//******************************************************************************
void GUA_AES_Encrypted(GUA_U8 *pGUA_AES_Data, GUA_U8 *pGUA_AES_EncryptedData)
{
LL_Encrypt(sbGUA_AES_Key, pGUA_AES_Data, pGUA_AES_EncryptedData);
}
//******************************************************************************
//name: GUA_AES_Deccrypted
//introduce: 解密16字节以内的数据
//parameter: pGUA_AES_EncryptedData:加密后的数据缓存区,必须16字节
// pGUA_AES_DeccryptedData:解密后的数据缓存区,必须16字节
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group: 香瓜BLE之CC2541(127442605)
//changetime: 2017.03.29
//******************************************************************************
void GUA_AES_Deccrypted(GUA_U8 *pGUA_AES_EncryptedData, GUA_U8 *pGUA_AES_DeccryptedData)
{
LL_EXT_Decrypt(sbGUA_AES_Key, pGUA_AES_EncryptedData, pGUA_AES_DeccryptedData);
}
//******************************************************************************
//name: GUA_AES_Init
//introduce: AES初始化
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group: 香瓜BLE之CC2541(127442605)
//changetime: 2017.03.29
//******************************************************************************
void GUA_AES_Init(void)
{
GUA_U8 nbGUA_LocalMac[6] = {0};
//获取mac
GUA_Get_LocalMac(nbGUA_LocalMac);
//通过mac获取秘钥
GUA_AES_GetKey(nbGUA_LocalMac, sbGUA_AES_Key);
}
2)写一个驱动头文件GUA_AES.h(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)
//******************************************************************************
//name: GUA_AES.h
//introduce: 香瓜的AES驱动的头文件
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group: 香瓜BLE之CC2541(127442605)
//changetime: 2017.03.29
//******************************************************************************
#ifndef _GUA_AES_H_
#define _GUA_AES_H_
/*********************宏定义************************/
//类型宏
#ifndef GUA_U8
typedef unsigned char GUA_U8;
#endif
#ifndef GUA_8
typedef signed char GUA_8;
#endif
#ifndef GUA_U16
typedef unsigned short GUA_U16;
#endif
#ifndef GUA_16
typedef signed short GUA_16;
#endif
#ifndef GUA_U32
typedef unsigned long GUA_U32;
#endif
#ifndef GUA_32
typedef signed long GUA_32;
#endif
#ifndef GUA_U64
typedef unsigned long long GUA_U64;
#endif
#ifndef GUA_64
typedef signed long long GUA_64;
#endif
/*********************外部函数************************/
extern void GUA_AES_Encrypted(GUA_U8 *pGUA_AES_Data, GUA_U8 *pGUA_AES_EncryptedData);
extern void GUA_AES_Deccrypted(GUA_U8 *pGUA_AES_EncryptedData, GUA_U8 *pGUA_AES_DeccryptedData);
extern void GUA_AES_Init(void);
#endif
3)工程中添加GUA_AES.c
4)在IAR设置中添加驱动源文件路径
$PROJ_DIR$\..\..\SimpleBLEPeripheral\Source\GUA
2、在应用层中使用
1)初始化(SimpleBLEPeripheral.c的SimpleBLEPeripheral_Init中)
//AES初始化
GUA_AES_Init();
2)添加驱动头文件(SimpleBLEPeripheral.c中)
#include "GUA_AES.h"
3)添加测试代码(SimpleBLEPeripheral.c的SimpleBLEPeripheral_Init中)
//AES测试
uint8 nbGUA_AES_Data[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; //需要加密的数据
static uint8 nbGUA_AES_EncryptedData[16] = {0}; //加密后数据存放区
static uint8 nbGUA_AES_DeccrypteData[16] = {0}; //解密后数据存放区
GUA_AES_Encrypted(nbGUA_AES_Data, nbGUA_AES_EncryptedData); //加密
GUA_AES_Deccrypted(nbGUA_AES_EncryptedData, nbGUA_AES_DeccrypteData); //解密
七、注意事项
1、实际项目使用中,加密与解密是在不同设备上的。
2、加密算法可自定义,香瓜仅仅是提供一种方法。
八、实验结果
设置断点在测试代码处,并仿真全速运行至断点处。
单步执行测试代码,可得下图实验结果:
因此,实验成功。