一臼氨、背景
一個 BLE 設(shè)備涛浙,可以使用兩種類型的地址(一個 BLE 設(shè)備可同時具備兩種地址):
- Public Device Address(公共設(shè)備地址)
- Random Device Address(隨機(jī)設(shè)備地址)可分為兩類:
- Static Device Address(靜態(tài)設(shè)備地址)
- Private Device Address(私密設(shè)備地址)又可分為兩類:
- Non-resolvable Private Address(不可解析私密地址)
-
Resolvable Private Address(可解析私密地址)
1.1 公共設(shè)備地址 Public Device Address
在通信系統(tǒng)中,設(shè)備地址是用來唯一識別一個物理設(shè)備的挤土,如TCP/IP網(wǎng)絡(luò)中的MAC地址檐束、傳統(tǒng)藍(lán)牙中藍(lán)牙地址等。對設(shè)備地址而言般码,一個重要的特性妻率,就是唯一性。
對于經(jīng)典藍(lán)牙(BR/EDR)來說板祝,其設(shè)備地址是一個 48bits 的數(shù)字宫静,稱作“48-bit universal LAN MAC address”。正常情況下,該地址需要向 IEEE 申請囊嘉,具有唯一性温技。
這種地址分配方式在 BLE 中也保留了下來,就是公共設(shè)備地址(Public Device Address)扭粱。由 24-bit 的 company_id 和 24-bit 的 company_assigned 組成。
高 24 位是公司標(biāo)識震檩,低 24 位公司內(nèi)部自己賦值琢蛤。
1.2 隨機(jī)設(shè)備地址 Random Device Address
但是,在 BLE 時代抛虏,只有公共設(shè)備地址明顯不夠用了博其,有如下原因:
- 公共設(shè)備地址需要向 IEEE 購買,需要一筆開銷迂猴。
- 公共設(shè)備地址的申請與管理相對繁瑣慕淡、復(fù)雜,再加上 BLE 設(shè)備的數(shù)量眾多(和傳統(tǒng)藍(lán)牙設(shè)備不是一個數(shù)量級的)沸毁,導(dǎo)致維護(hù)成本增大峰髓。
- 安全因素。BLE 很大一部分的應(yīng)用場景是廣播通信息尺,這意味著只要知道設(shè)備的地址携兵,就可以獲取所有的信息,這是很不安全的搂誉。因此固定的設(shè)備地址徐紧,加大了信息泄露的風(fēng)險。
為了解決上述問題炭懊,BLE 協(xié)議新增了一種地址:隨機(jī)設(shè)備地址并级,即設(shè)備地址不是固定分配的,而是在設(shè)備啟動后隨機(jī)生成的侮腹。根據(jù)不同的目的嘲碧,隨機(jī)設(shè)備地址分為靜態(tài)設(shè)備地址和私密設(shè)備地址。
1.2.1 靜態(tài)設(shè)備地址 Static Device Address
靜態(tài)設(shè)備地址是設(shè)備在上電時隨機(jī)生成的地址凯旋,NRF52832 官方工程默認(rèn)都是使用靜態(tài)地址
呀潭,其格式如下:
靜態(tài)設(shè)備地址的特征可總結(jié)為:
- 最高兩個 bit 為 “11”。
- 剩余的 46bits 是一個隨機(jī)數(shù)至非,不能全部為0钠署,也不能全部為1。
- 在一個上電周期內(nèi)保持不變荒椭。
- 下一次上電的時候可以改變谐鼎。但不是強(qiáng)制的,因此也可以保持不變趣惠。如果改變狸棍,上次保存的連接等信息身害,將不再有效。
靜態(tài)設(shè)備地址的使用場景可總結(jié)為:
- 46bits 的隨機(jī)數(shù)草戈,可以很好地解決“設(shè)備地址唯一性”的問題塌鸯,因?yàn)閮蓚€地址相同的概率很小。
- 地址隨機(jī)生成唐片,可以解決公共設(shè)備地址申請所帶來的費(fèi)用和維護(hù)問題丙猬。
1.2.2 私密設(shè)備地址 Private Device Address
靜態(tài)設(shè)備地址通過地址隨機(jī)生成的方式,解決了部分問題费韭。私密設(shè)備地址則更進(jìn)一步茧球,通過定時更新和地址加密兩種方式,提高藍(lán)牙地址的可靠性和安全性星持。根據(jù)設(shè)備地址是否加密抢埋,又分為兩類:
① 不可解析私密地址 Non-resolvable Private Address
不可解析私密地址和靜態(tài)設(shè)備地址類似,不同之處在于不可解析私密地址會定時更新督暂。更新的周期是由 GAP 規(guī)定的揪垄,稱作 T_GAP(private_addr_int),建議值是 15 分鐘损痰。其格式如下:
不可解析私密地址的特征可總結(jié)為:
- 最高兩個 bit 為 “00”福侈。
- 剩余的 46bits 是一個隨機(jī)數(shù),不能全部為0卢未,也不能全部為1肪凛。
- 以 T_GAP(private_addr_int) 為周期,定時更新辽社。
② 可解析私密地址 Resolvable Private Address
可解析私密地址比較有用伟墙,它通過一個隨機(jī)數(shù)和一個稱作 identity resolving key(IRK) 的密碼生成,因此只能被擁有相同 IRK 的設(shè)備掃描到滴铅,可以防止被未知設(shè)備掃描和追蹤戳葵。其格式如下:
可解析私密地址的特征可總結(jié)為:
- 高位 24bits 是隨機(jī)數(shù)部分,其中最高兩個 bit 為“10”汉匙,用于標(biāo)識地址類型拱烁;低位 24bits 是隨機(jī)數(shù)和 IRK 經(jīng)過 hash 運(yùn)算得到的 hash值,運(yùn)算公式為 hash = ah(IRK, prand)噩翠。
- 當(dāng)主端 BLE 設(shè)備掃描到該類型的藍(lán)牙地址后戏自,會使用保存在本機(jī)的 IRK,和該地址中的 prand伤锚,進(jìn)行同樣的 hash 運(yùn)算擅笔,并將運(yùn)算結(jié)果和地址中的 hash 字段比較,相同的時候,才進(jìn)行后續(xù)的操作猛们。這個過程稱作 resolve(解析)念脯,如果不同則繼續(xù)用下一個 IRK 做上面的過程,直到找到一個關(guān)聯(lián) IRK 或者一個也沒找到弯淘。
- 以T_GAP(private_addr_int) 為周期绿店,定時更新。哪怕在廣播庐橙、掃描惯吕、已連接等過程中,也可能改變怕午。
- Resolvable Private Address 不能單獨(dú)使用,因此需要使用該類型的地址的話淹魄,設(shè)備要同時具備 Public Device Address 或者 Static Device Address 中的一種郁惜。
二、分析廣播包中藍(lán)牙MAC地址
使用抓包工具抓取類似如下數(shù)據(jù)包:
其中數(shù)據(jù)包第 6 部分:
其中 TxAdd 表示發(fā)送方的地址類型(0 為 public甲锡,1為 random)兆蕉。
RxAdd 表示接收方的地址類型。
對于普通廣播來說缤沦,只有 TxAdd 的指示是有效的虎韵,表示廣播發(fā)送者的第一類型。而對于定向廣播來說缸废,TxAdd 和 RxAdd 都是有效的包蓝。
其中數(shù)據(jù)包第 7 部分:
如果是隨機(jī)設(shè)備地址,則查看地址的最高兩位企量。
- 如果是 “11” 就是靜態(tài)隨機(jī)地址测萎。
- 如果是 “00” 就是不可解析私密地址。
- 如果是 “01” 就是可解析私密地址届巩,并執(zhí)行上面說過的 ah 方法進(jìn)行解析硅瞧。
三、讀取MAC地址
- 包含頭文件
#include "ble_gap.h"
- 定義結(jié)構(gòu)體變量
ble_gap_addr_t bleAddr;
BLE 的地址由 ble_gap_addr_t
進(jìn)行管理:
/**@brief Bluetooth Low Energy address. */
typedef struct
{
uint8_t addr_id_peer : 1; /**< Only valid for peer addresses.
This bit is set by the SoftDevice to indicate whether the address has been resolved from
a Resolvable Private Address (when the peer is using privacy).
If set to 1, @ref addr and @ref addr_type refer to the identity address of the resolved address.
This bit is ignored when a variable of type @ref ble_gap_addr_t is used as input to API functions. */
uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */
uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format.
@ref addr is not used if @ref addr_type is @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. */
} ble_gap_addr_t;
- addr_id_peer:僅對匹配地址有效恕汇。此位由軟件設(shè)置腕唧,以指示該地址是否已從可解析私密地址中解析(當(dāng)匹配加密時)
- addr_type:地址類型,作為傳入?yún)?shù)時可忽略
- addr:48-bit 的MAC地址數(shù)組瘾英,低字節(jié)在前枣接,所以與我們實(shí)際看到的地址順序相反
- 調(diào)用獲取地址函數(shù)
uint32_t sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)
sd_ble_gap_addr_get(&bleAddr);
- 將地址逆序并打印出來
#include "nrf_log.h"
uint8 address[6];
uint8 i;
for(i = 0; i < 6; i++)
{
address[i] = bleAddr.addr[5 - i]; // 逆序
}
NRF_LOG_INFO("address:%02x", address[0]);
NRF_LOG_INFO("address:%02x", address[1]);
NRF_LOG_INFO("address:%02x", address[2]);
NRF_LOG_INFO("address:%02x", address[3]);
NRF_LOG_INFO("address:%02x", address[4]);
NRF_LOG_INFO("address:%02x", address[5]);
這樣打印出來的地址就跟我們實(shí)際掃描到的地址順序相同。
四方咆、修改MAC地址
首先采用 sd_ble_gap_addr_get
讀取官方默認(rèn)的 MAC 地址月腋,然后再默認(rèn)地址+1,再用 sd_ble_gap_addr_set
寫入到設(shè)備中。
void mac_set(void)
{
ble_gap_addr_t addr;
uint32_t err_code = sd_ble_gap_addr_get(&addr);
APP_ERROR_CHECK(err_code);
// Increase the BLE address by one when advertising openly.
addr.addr[0] += 1;
err_code = sd_ble_gap_addr_set(&addr);
APP_ERROR_CHECK(err_code);
}
主函數(shù)中進(jìn)行調(diào)用榆骚,注意片拍,一定要在廣播開始前設(shè)置,下次廣播后新的 MAC 地址就設(shè)置成功妓肢。
/**@brief Application main function.
*/
int main(void)
{
bool erase_bonds;
// Initialize.
uart_init();
log_init();
timers_init();
buttons_leds_init(&erase_bonds);
power_management_init();
ble_stack_init();
gap_params_init();
mac_set();
gatt_init();
services_init();
advertising_init();
conn_params_init();
// Start execution.
advertising_start();
// Enter main loop.
for (;;)
{
idle_state_handle();
}
}
新的 MAC 地址加1捌省,設(shè)置成功。
? 由 Leung 寫于 2020 年 2 月 19 日
? 參考:青風(fēng)電子社區(qū)