低功耗蓝牙BLE之AES-128加密算法
Posted 枫之星雨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了低功耗蓝牙BLE之AES-128加密算法相关的知识,希望对你有一定的参考价值。
版权声明:
博主:枫之星雨
声明:本文为博主原创文章,转载请注明原文出处。
博文地址:点击进入
邮箱:454086991@qq.com
QQ号:454086991(申请加好友时请备注”技术交流“)
加密
在连接时,可以对净荷中的数据进行加密,确保数据的机密性,从而抵御攻击者。机密性是指第三方“攻击者”由于没有加密链路的共享密钥,因此无法拦截、破译或读取消息的原始内容。
加密数据包含一个消息完整性校验值,表明该数据包已经过认证。为了验明发送方的有效身份,认证使用共享密钥为已加密的数据计算签名,可防止第三方篡改数据包中的任何内容。通过认证,消息的接收方能够确信收到的数据包来自一个可信设备。
加密数据包还包含一个数据包计数器,用来防止重放攻击。重放攻击是这样一种攻击方式:攻击者截取一个既有的消息,随后再次发送该消息以期望收到响应。试想,假如没有重放攻击保护,攻击者有可能扫描到某个设备的大量数据包,然后再次发送这些数据包,其结果可能不堪设想。显然,防止重放攻击是一件非常重要的事情。
AES-128加密算法简介
低功耗蓝牙中的所有加密和认证都基于同一个加密引擎,称为高级加密系统(AES)。AES最初源自美国的一项政府计划,试图寻找未来可用的加密引擎。一直以来,AES被用于许多有线和无线标准,迄今为止安全研究人员还没有找到其算法的弱点。
AES可以有多种形式,取决于在给定的时间内能够处理的数据块以及密钥的大小。低功耗蓝牙使用128位的密钥和128位的数据块。也就是说,所有密钥的长度均为128位,每次加密生成的密文长度为16个字节。
AES加密块非常简单,它包含两个输入和一个输出。两个输入分别为128位的密钥值和128位的纯文本数据块,输出则为128位的加密数据块。密钥和纯文本在使用上有一些不同;纯文本可以直接为加密块使用,但密钥必须经过处理后才能使用。可见,更有效的方法是只设立一个密钥,用于不同的纯文本块以进行快速加密,而非使用不同的密钥为每个块加密。
在低功耗蓝牙里,AES加密引擎被用于下列四个基本功能:
1.加密净荷数据
2.计算消息完整性校验值
3.数据签名
4.生成私有地址
数据签名在安全管理器中定义,生成私有地址在通用访问规范中定义。
注意,本文主要是为了讲解AES-128算法在BLE设备和安卓手机之间通信时使用的过程,所以并没有去深入研究讲解AES算法。如果有对该算法感兴趣的,可以去网上搜索相关资料深入了解一下。
AES-128加解密方法源码
我们的实验案例是BLE设备端(从机)发送加密的数据给安卓手机(主机)并解密出原始有效数据,以及安卓手机(主机)发送加密的数据给BLE设备端(从机)并解密出原始有效数据。通信过程不便于演示,所以我们换种方式来呈现我们的实现源码:同样的原始有效数据,同样的加解密Key,分别在设备端和Java测试环境中对原始有效数据进行加密然后解密,通过看设备端和Java测试环境中加密之后的数据是否一致以及解密之后的数据是否一致,来判断我们的数据加密传输能否成功,如果加密之后数据一致并且解密之后的数据也一致,那加密传输就可以成功实现。
1.BLE设备端测试程序。
(1)测试环境:
开发环境:IAR8.20版本,Windows XP系统
测试设备:CC2541/CC2540开发板
测试例程:1.4.0协议栈中“simpleBLEPeripheral”例程
(2)实现源码:
/****************************************************************
* 名 称: Aes128EncryptAndDecrypTest()
*
* 功 能: 测试AES-128 加解密,注意我们加密时需要key,
* 加密后的数据用于通信;同样解密的时候也
* 需要用同一个key进行解密,这样,如果对方
* 没有key 就无法解密出原始数据,进而保护了
* 用户数据不被截取。
*
* 入口参数: 无
* 出口参数: 无
****************************************************************/
static void Aes128EncryptAndDecrypTest(void)
{
int i = 0;
// 加密秘钥 16个字节也就是128 bit
uint8 key[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
// 需要加密的数据(保证16个字节,不够的自己填充)
uint8 source_buf[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
// 加密后数据存放区
uint8 encrypted_buf[16];
// 解密后数据存放区
uint8 deccrypted_buf[16];
// 开始加密,加密后的数据存放到encrypted_buf
LL_Encrypt( key, source_buf, encrypted_buf );
// 开始解密,将解密后的数据存到deccrypted_buf
LL_EXT_Decrypt( key, encrypted_buf, deccrypted_buf );
//打印原始数据
tx_printf("source:");
for(i = 0;i < 16;i++)
{
txprintf("0x%02x ",source_buf[i]);
}
tx_printf("");
//打印加密后的数据
tx_printf("encrypte:");
for(i = 0;i < 16;i++)
{
txprintf("0x%02x ",encrypted_buf[i]);
}
tx_printf("");
//打印解密后的数据
tx_printf("deccrypte:");
for(i = 0;i < 16;i++)
{
txprintf("0x%02x ",deccrypted_buf[i]);
}
tx_printf("");
}
上述测试方法放到“simpleBLEPeripheral.c”文件中,在初始化函数“SimpleBLEPeripheral_Init”里面最后的地方调用上述测试方法“Aes128EncryptAndDecrypTest();”就可以了。
通过上述测试方法,我们看到设备端加密用的是“LL_Encrypt”方法,解密用的是“LL_EXT_Decrypt”方法,这两个方法的声明在“Ll.h”头文件中,这个头文件被“hci.h”头文件引用,所以如果提示找不到这两个方法的时候,我们引用“hci.h”头文件即可。因为上面的注释比较详细,所以我们就不再赘述了。
(3)测试结果:
以上是关于低功耗蓝牙BLE之AES-128加密算法的主要内容,如果未能解决你的问题,请参考以下文章
Android上的BLE(蓝牙低功耗蓝牙),创建并重新连接到并不总是存在的设备