動態密碼

涉及 配對與綁定 相關知識。

這裏準確的說法應該是叫配對碼,而不是密碼。輸入這個這個配對碼是配對過程中可選的一部分。

我們需要的輸入“密碼”這個功能,其實是配對過程中的一部分。而配對過程又是需要首先交換配對信息,然後協議棧會根據交換的信息才決定是否有輸入密碼這一過程。

無論是靜態密碼還是動態密碼(配對碼,後面統一叫密碼)都是可以看做是配對過程中的一種認證方式即我是我,因爲這樣可以一定程度上避免他人連接你的設備,因爲他們看不到設備上顯示的配對碼,而你自己去可以看到。

配對碼的輸入是配對過程中生成TK的一種方式即Passkey Entry。另外還有Just Works和Out of Band 兩種方式。TK的生成是爲了後續再生成STK用來加密鏈路然後分發LTK,IRK,CSRK。(如果配對信息交換是沒是指明綁定也就不需要後續的這裏密鑰的分發了)。


動態密碼設置 :

這裏只是演示動態密碼,不需要綁定

認證方式就是 :passkey entery。

因爲是動態密碼,板子上沒有顯示屏,所以通過串口將動態密碼打印出來,然後手機正確輸入才能配對成功。


//設置動態密碼步驟 細分詳解:
//步驟一

//設置配對時要交換的信息:
//這裏只是演示靜態密碼,不需要綁定
#define SEC_PARAM_BOND 0
//因爲要輸入密碼,就是一種MITM攻擊保護,所以這裏設置MITM
#define SEC_PARAM_MITM 1
//這裏設置只有現實屏(其實沒有,但是我們用的是事先知道的靜態密碼,不需要顯示)
#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_DISPLAY_ONLY
//不使用帶外數據
#define SEC_PARAM_OOB 0
//鏈路加密密鑰的長度
#define SEC_PARAM_MIN_KEY_SIZE 7
#define SEC_PARAM_MAX_KEY_SIZE 16
//定義全局變量, 設置配對啓動後交換的信息.
ble_gap_sec_params_t  m_sec_params;

//初始化  配對啓動後交換的信息.該函數放在 int main(void) 裏的 conn_params_init();後.
void sec_params_init(void)
{
m_sec_params.bond = SEC_PARAM_BOND;
m_sec_params.mitm = SEC_PARAM_MITM;
m_sec_params.io_caps = SEC_PARAM_IO_CAPABILITIES;
m_sec_params.oob = SEC_PARAM_OOB;
m_sec_params.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
m_sec_params.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
}


//步驟二
//觸發配對信息發給對端設備,修改在 ble_nus.c

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_OPEN(&cccd_md.write_perm);

//步驟二
//觸發配對信息發給對端設備
//將上面一行改爲下面一行,這樣手機使能板子的rx特徵值得notify功能時,
//就會因爲因爲沒有寫權限而觸發配對,手機就會發來配對請求,
//然後板子回覆配對信息. 怎麼回覆?看步驟三.
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&cccd_md.write_perm);


    cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    memset(&char_md, 0, sizeof(char_md));
    char_md.char_props.notify = 1;
    char_md.p_char_user_desc  = NULL;
    char_md.p_char_pf         = NULL;
    char_md.p_user_desc_md    = NULL;
    char_md.p_cccd_md         = &cccd_md;
    char_md.p_sccd_md         = NULL;
    ble_uuid.type = p_nus->uuid_type;
    ble_uuid.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC;
    memset(&attr_md, 0, sizeof(attr_md));

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);

    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth = 0;
    attr_md.wr_auth = 0;
    attr_md.vlen    = 1;
    memset(&attr_char_value, 0, sizeof(attr_char_value));
    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = sizeof(uint8_t);
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = BLE_NUS_MAX_RX_CHAR_LEN;
    return sd_ble_gatts_characteristic_add(p_nus->service_handle,
                                           &char_md,
                                           &attr_char_value,
                                           &p_nus->rx_handles);
    /**@snippet [Adding proprietary characteristic to S110 SoftDevice] */
}


//步驟三

信息交換完後,設備低層的協議棧就會自動產生6爲隨機的密碼(配對碼),並將配對碼通過事件BLE_GAP_EVT_PASSKEY_DISPLAY 上拋app,然後就可以在app中將密碼通過串口將密碼打印出來了。

和判斷配對是否成功,如果不成功斷開連接,從而阻止他人任意連接。

static void on_ble_evt(ble_evt_t * p_ble_evt)

{

    case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
    //err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);

    sec_params_init();
    err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, NULL);
    APP_ERROR_CHECK(err_code);
    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_GAP_EVT_AUTH_STATUS:
  if(p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS)
  {
      printf("pair success\r\n");
  }
  else
  {
      err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);

      APP_ERROR_CHECK(err_code);
  }
  break;

}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章