【BLE】CC2541之数据加密与解密(利用MAC形成自定义秘钥)

本篇博文最后修改时间: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

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
香瓜单片机之Linux群:512598061
香瓜单片机之职场交流群:450154342
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、 实验前提
1、在进行本文步骤前,请先 阅读 以下博文:
1)《CC2541之数据加密与解密》:http://blog.csdn.net/feilusia/article/details/50085225

2、在进行本文步骤前,请先 实现以下博文:
暂无


五、基础知识

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、加密算法可自定义,香瓜仅仅是提供一种方法。


八、实验结果

设置断点在测试代码处,并仿真全速运行至断点处。

单步执行测试代码,可得下图实验结果:


可见数据“1、2、3……16”经过加密,再经过解密,最终保存到了nbGUA_AES_DeccrypteData数组中。

因此,实验成功。



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值