前段时间学习了ble加密解密。其实核心就是LL_Encrypt和LL_EXT_Decrypt()
网上大多数教程都是只在一个工程里运行仿真,感觉没有将蓝牙加密传输提现,所以这里用btool和一个cc2541进行加密传输,
这里只提供思路给大家参考下
一、slave端
1、创建特征值char6,这里个特征值特殊点就是要有16个数据长度
注:这里说下为什么设置成16位,应为我想得是LL_Encrypt和LL_EXT_Decrypt()的参数都是16位的,如果不把新的特征值设置成16位,那么传输给hosttest的加密数据不足16位,在解密时自己补0,解密的数据就不对了。
2、初值
在simpleBLEPeripheral.c的SimpleBLEPeripheral_Init添加初始化,初始化为
uint8 charValue6[SIMPLEPROFILE_CHAR6_LEN] = { 1, 2, 3, 4, 5,6,7,8,9,10,11,12,13,14,15,16 };
3、被读取时的操作
在simpleGATTprofile.c的simpleProfile_ReadAttrCB修改
static bStatus_t simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 *pLen, uint16 offset,
uint8 maxLen, uint8 method )
{
uint8 key[16]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
static uint8 EncryptedData[16]={0};
bStatus_t status = SUCCESS;
// If attribute permissions require authorization to read, return error
if ( gattPermitAuthorRead( pAttr->permissions ) )
{
// Insufficient authorization
return ( ATT_ERR_INSUFFICIENT_AUTHOR );
}
// Make sure it's not a blob operation (no attributes in the profile are long)
if ( offset > 0 )
{
return ( ATT_ERR_ATTR_NOT_LONG );
}
if ( pAttr->type.len == ATT_BT_UUID_SIZE )
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch ( uuid )
{
case SIMPLEPROFILE_CHAR6_UUID:
*pLen=SIMPLEPROFILE_CHAR6_LEN;
LL_Encrypt(key,pAttr->pValue,EncryptedData);//加密
VOID osal_memcpy(pValue,EncryptedData,SIMPLEPROFILE_CHAR6_LEN);
//VOID osal_memcpy(pValue,pAttr->pValue,SIMPLEPROFILE_CHAR6_LEN);
break;
。。。。。
二、master
1、选择工程
首先确定的是对象是USB dongle,用的也是协议栈自带的hosttest工程,需要注意的是用的是cc2540工程
2、解密数据
解密时在应用层也就是在GATT层,通过sniffer抓数据知道对应功能码是ATT_READ_BY_TYPE_RSP,
在hci_ext_app.c的processEventsGATT修改
添加
uint8 key[16]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
static uint8 DecryptedData[16]={0};
修改
case ATT_READ_BY_TYPE_RSP:
{
attReadByTypeRsp_t *pRsp = &pPkt->msg.readByTypeRsp;
attHdrLen = ATT_READ_BY_TYPE_RSP_FIXED_SIZE;
// Copy request header over
msgLen = ATT_BuildReadByTypeRsp( &pOutMsg[hdrLen], (uint8 *)pRsp ) - attHdrLen;
//解密只用到加密的数据,前面连个是数是功能码和数据长度
osal_memcpy(temp,pRsp->pDataList,msgLen);
for(int i=0;i<16;i++)
{
temp1[i]=temp[i+2];
}
LL_EXT_Decrypt(key, temp1,DecryptedData);
//后面的数据又要功能码和数据长度
for(int i=0;i<18;i++)
{
temp[i+2]=DecryptedData[i];
}
pPayload =temp;
//pPayload = pRsp->pDataList;
}
break;
三、实验现象
可以看到sniffer抓到的数据是没有规则的
但是在btool中和在slave给的初始值一样,所以加密解密成功
四、总结
这里只是简略的说了下读加密数据,写加密数据也是一个思路。还有不足时每次都得读16个数据,但是暂时也想不到更好的方法了。