BLE-NRF51822教程10—动态密码(配对码)
本講教程也是在?sdk中的的uart例子 的基礎上修改實現動態密碼(其實是配對碼)的功能。Uart例子在以下目錄中
XXX\Keil_v5\ARM\Pack\NordicSemiconductor\nRF_Examples\9.0.0\ble_peripheral\ble_app_uart
?
關于配對的一些理論知識在靜態密碼教程中有介紹。這里就不再贅述。
?
因為是動態密碼,板子上沒有顯示屏,所以通過串口將動態密碼打印出來,然后手機正確輸入才能配對成功。
?
無論是靜態密碼還是動態密碼(配對碼,后面統一叫密碼)都是可以看做是配對過程中的一種認證方式即”我是我”,因為這樣可以一定程度上避免他人連接你的設備,因為他們看不到設備上顯示的配對碼,而你自己去可以看到。
?
配對碼的輸入是配對過程中生成TK的一種方式即Passkey Entry。另外還有Just Works和Out of Band?兩種方式。TK的生成是為了后續再生成STK用來加密鏈路然后分發LTK,IRK,CSRK。(如果配對信息交換是沒是指明綁定也就不需要后續的這里密鑰的分發了)
?
既然有三種方式可選,那么協議是如何決定選擇哪種的呢。這個就和配對時交換的配對信息有關了。我們使用的是Passkey Entry?即輸入配對碼的方式,那么只要將 配對信息中的 OOB設置為0 ,MITM設置為 1, bond設置為0(教程只是演示配對中的配對碼的輸入不需要后面的密鑰分發過程),然后將自己的 I/O能力設置為?DisplayOnly??就行了。
?
:至于各種可能的組合會導致選擇什么樣的方式在規范的安全管理部分有詳細的對照表可參考。
?
根據上面的描述,我們首先就是要配置配對時要交換的配對信息
?
#define IO_CAPS????? BLE_GAP_IO_CAPS_DISPLAY_ONLY? //只有顯示裝置
#define BOND???????? 0?????????????????????????????? //不綁定
#define OOB????????? 0??????????????????????????
#define MITM???????? 1
?
?然后就是在程序中回復配對信息。
實現如下函數來回復配對請求信息并將自己的配對信息傳給對方。
?
void resp_pair_request(){
??? ble_gap_sec_params_t sec_params;
??? uint32_t??????????????????? err_code;
???
??? memset(&sec_params,0,sizeof(ble_gap_sec_params_t));
??? sec_params.bond = BOND;
??? sec_params.io_caps = IO_CAPS;
??? sec_params.max_key_size = 16;
??? sec_params.min_key_size = 7;
??? sec_params.oob = BOND;
??? sec_params.mitm = MITM;
err_code=sd_ble_gap_sec_params_reply(m_conn_handle,BLE_GAP_SEC_STATUS_SUCCESS,&sec_params,NULL);
??? APP_ERROR_CHECK(err_code);
}
?
?
?
將該函數添加到BLE_GAP_EVT_SEC_PARAMS_REQUEST事件處理部分中去。這樣在主機請求配對時,從機就可以將自己的配對信息發送給主機了。
?
信息交換完后,設備低層的協議棧就會自動產生6為隨機的密碼(配對碼),并將配對碼通過事件BLE_GAP_EVT_PASSKEY_DISPLAY?上拋給app,然后就可以在app中將密碼通過串口將密碼打印出來了。
?
上面說的兩個事件的處理我們都在?on_ble_evt?事件處理函數中處理。紅色代碼部分為處理函數。
static void on_ble_evt(ble_evt_t * p_ble_evt)
{
??? uint32_t???????????????????????? err_code;
???
??? switch (p_ble_evt->header.evt_id)
??? {
??????? case BLE_GAP_EVT_CONNECTED:
??????????? err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
??????????? APP_ERROR_CHECK(err_code);
??????????? m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
??????????? break;
???????????
??????? case BLE_GAP_EVT_DISCONNECTED:
??????????? err_code = bsp_indication_set(BSP_INDICATE_IDLE);
??????????? APP_ERROR_CHECK(err_code);
??????????? m_conn_handle = BLE_CONN_HANDLE_INVALID;
??????????? break;
?
????????case?BLE_GAP_EVT_SEC_PARAMS_REQUEST:
??????????? printf("receive pair request\n");
? ??????? ?resp_pair_request();
??????????? break;
???????case?BLE_GAP_EVT_PASSKEY_DISPLAY:
???????? ?printf("show passkey: ")
???????? for ( int i = 0; i < 6; i++){??????? ???????? ? ??????????????? printf("%c",p_ble_evt->evt.gap_evt.params. \
?????????????????? passkey_display.passkey[i]);
???????? }
?????????? ? break;??
?????????????????
??????? case BLE_GATTS_EVT_SYS_ATTR_MISSING:
??????????? // No system attributes have been stored.
??????????? err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
??????????? APP_ERROR_CHECK(err_code);
??????????? break;
?
??????? default:
??????????? // No implementation needed.
??????????? break;
??? }
}
?
然后添加觸發配對代碼。 這里實現的很簡單。就是將Rx特征值的cccd的寫設置成需要鏈路加密和MITM。這樣在未配對的情況下手機使能Notify時設備就會回復權限不足,然后手機就會發一個配對請求過來從而實現配對和鏈路的加密。
?
修改ble_nus.c文件中的rx_char_add函數。
static uint32_t rx_char_add(ble_nus_t * p_nus,
?const ble_nus_init_t * p_nus_init)
{
??? /**@snippet [Adding proprietary characteristic to S110 SoftDevice] */
??? ble_gatts_char_md_t char_md;
??? ble_gatts_attr_md_t cccd_md;
??? ble_gatts_attr_t??? attr_char_value;
??? ble_uuid_t????????? ble_uuid;
??? ble_gatts_attr_md_t attr_md;
?
??? memset(&cccd_md, 0, sizeof(cccd_md));
?
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
//設置權限
????BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&cccd_md.write_perm);
?? // BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
?? …………
?? …………
?
}
?
之后燒錄程序后,在手機執行使能Notify時就會觸發配對,串口會打印出隨機密碼,手機正確輸入后便是成功配對。
總結
以上是生活随笔為你收集整理的BLE-NRF51822教程10—动态密码(配对码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nrf51822笔记之密码配对过程梳理
- 下一篇: nrf51822-配对绑定实现过程