nordicBLE 通信グループ 498676838
この講義では、ペアリングに関する関連理論的知識を紹介し、「静的パスワード」の設定を実現する方法を紹介します
プログラムは以下に基づいていますsdk9.0 uart デモ
また、テストに使用したモバイル アプリは IOS ではライトブルーです。
ここでの正しい用語は、パスワードではなく、ペアリングコードと呼ぶべきです。このペアリング コードの入力は、ペアリング プロセスのオプションの部分です
静的パスワードの設定方法を紹介する前に、ペアリング (後でペアリング コードではなくパスワードと呼ばれます) に関連する知識を紹介しましょう
最初はそうではありませんでした。セキュリティを必要とする作業を実行したい場合は、セキュリティを提供する 2 台のデバイスを最初にペアリングする必要があります。ペアリングには、2 つのデバイスの認証とリンクの暗号化が含まれます。ペアリング時にバインディングビットを設定すると、後で秘密鍵が配布されます。ユーザーが割り当てた秘密キーをフラッシュに保存できるため、2 つのデバイスが 2 回目に再接続するときのセキュア ブートが高速になります。初回のようにペアリングプロセス全体を再度開始する必要はありません。
ペアリングの最初のプロセスは、認証方法と、その後配布する必要がある鍵の有無とどの鍵を配布するかを決定するために使用されるペアリング情報の交換から始まります。
交換される情報には以下が含まれます:
ディスプレイ画面やキーボードの有無など、両端のデバイスの入出力機能。
バインディングが必要かどうか (バインディング ビットがペアリングに設定されている場合)。
MITM が必要かどうか、OOB を使用するかどうかなど
この情報により、BLE プロトコル スタックは認証方法を決定します:
例:
1: デバイスの入力および出力機能の場合キーボードがないなど、両端のデバイスが制限されています。ディスプレイの場合、認証方法は機能するだけです。これは、実際には認証がないことを意味します
2: 両端のデバイスの一方にディスプレイ周波数があり、もう一方にディスプレイ周波数がある場合。キーボードとのペアリングで MITM 保護が設定されています。次に、認証方法はパスキー入力です。
一方の端にペアリングコードが表示され、もう一方の端でペアリングコードを入力する必要があります。そうすることでのみ、ペアリングを正しく進めることができます。
3: OOB が設定されている場合、ペアリング コードは、上記のように一方の端で表示され、もう一方の端で入力されるのではなく、別の通信方法 (NFC など) を通じて送信されます。
このレッスンのパスワード設定は 2 番目のケースです。表示されるパスワードはランダムまたは静的です。端末にディスプレイがないからです。ただし、静的パスワードを使用しているため、入出力機能を設定してディスプレイを表示することはできます。
ペアリングプロセスは、ペアリングコードを入力するだけでなく、入力されたペアリングコードと両端のデバイスによって交換される乱数に基づいて、リンクを暗号化し、その後のキーを割り当てるためのリンクキーを生成します。ペアリングには多くの理論があり、上記の説明は大まかなプロセスにすぎません。ペアリングのプロセスについては、Bluetooth 仕様のセキュリティの章で詳しく説明されています。
上記の理論的な説明に基づいて、要約しましょう:
「パスワード」を入力する必要がある機能は、実際にはペアリングプロセスの一部です。ペアリング プロセスでは、最初にペアリング情報を交換する必要があり、その後プロトコル スタックが交換された情報に基づいてパスワードを入力するかどうかを決定します。
次に、私たちがしなければならないことは次のステップです:
1: まず入力する静的パスワードを設定します
2: ペアリング中に交換される情報を設定します: 上記の紹介に従って、必要に応じて携帯電話でパスワードを入力し、ペアリングします。 セットアップする必要があるのはモニターのみです(これは、一方の端で表示され、もう一方の端で入力されます。実際にはモニターはありませんが、静的なものを設定しても問題ありません)パスワード)。この設定には MITM 攻撃保護が必要です。
3: ペアリングをトリガーします。
まず、静的パスワードを設定する方法を紹介します:
staticble_opt_t m_static_pin_option;
これら 2 つのパラメータを定義した後、設定操作で静的パスワードを設定する必要があります。したがって、次のように、gap_params_init() 関数の最後にパスワード設定操作を追加します。前の手順では、いくつかのデバイス名とその後のニーズを設定します ネゴシエートされた接続パラメータ //詳細な説明はシリアル ポートの透過的伝送解析で説明されています
uint32_t err_code;
ble_gap_conn_params_tgap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;
BLE_ GAP_CONN_SEC_MODE_SET_OPEN (&sec_mode);
err_code=sd_ble_gap_device_name_set (&sec_mode,
(constuint8_t*DEVICE_NAME,trlen(DEVICE_NAME));
APP_ERROR_CHECK(err_code);
memset(&gap_conn_params, 0,sizeof(gap_conn_params));
gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
gap_conn_params.max_conn_interval = MAX _CON N_INTERVAL;
gap_conn_params.slave_latency= SLAVE_LATENCY;
gap_conn_params.conn_sup_timeout= CONN_SUP_TIMEOUT ;
err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
APP_ERROR_CHECK(err_code);
//以下の操作です静的パスワードを設定するには
u int8_tpasskey[] = STATIC_PASSKEY; m_static_pin_option.gap_opt.passkey. p_passkey= passkey;
//このシステムコールはパスワード設定操作を実行します。
err_code=sd_ble_opt_set(BLE_GAP_OPT_PASSKEY,&m_static_pin_option)
APP_ERROR_CHECK(err_code);
}
これで静的パスワードの設定操作は完了です。
次に、ペアリングを設定するときに交換される情報:
以下は、交換する必要がある情報のマクロ、つまりセキュリティパラメータに関連するいくつかのマクロを定義します。
//これは単なる静的パスワードのデモンストレーションであり、バインディングは必要ありません
#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
マクロを定義した後、次のようにパラメータを設定し、関数を記述する必要があります。
m_sec_params はグローバル変数です
ble_gap_sec_params_t m_sec_params;
static 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;
}
この関数を main 関数の初期化プロセスの conn_params_init() 関数の後に配置します。 。
グローバル変数セットは、ペアリング開始後の情報交換に使用されます(内部の値が交換する情報となるため)。
ここではペアリング開始後に交換する情報を設定します。しかし、この情報をピアデバイスにどのように提供するのでしょうか? まず、ペアリングをトリガーする最後のステップを読んでから、ペアリング情報をピア デバイスに送信する問題を解決します。
ペアリングをトリガーする最後のステップ:
ペアリングは次の状況でトリガーできます:
1: ホストによって直接開始されます。
2: スレーブが以前にバインドされている場合、ホストは保存された LTK 暗号化リンクを直接使用します。そうでない場合、ホストはペアリング リクエストを開始します。
3: BLE にはセーフ モードの概念があります。暗号化されたリンク アクセスに認証を要求するように属性が設定されている場合、ホストがスレーブの属性デバイスにアクセスすると、リンクが安全でない場合はエラーが返され、ホストはセキュリティ要件を達成するためにペアリング要求を開始します。
ホストがトリガーするのを受動的に待つ 3 番目の方法を使用します。次に、最初にアクセスするために安全なリンクを要求するようにいくつかの属性を設定します。その後、電話がアクセスされるとペアリング プロセスをトリガーします。
9.0SDK の uartdemo に基づいているため、認証と暗号化を必要とする安全なリンクとして、通知プロパティ RX 機能値を持つ cccd (クライアント構成記述子) を設定します。
携帯電話で通知を有効にするには、CCCDを書き込む必要があるため
そのため、ボードに手を接続してrx特性値の通知ボタンをクリックすると、ホストは、CCCDを書き込むための書き込みコマンドを送信します。ボード上の rx 特性値。最初にテストされたリンクが不完全であるため、電話機は書き込みエラーを返し、ペアリング プロセスを開始します。
次のように設定します:
RX 固有値を追加する関数で次の簡単な操作を実行するだけです。
ここではコードの一部のみがインターセプトされます:
static uint32_t rx_char_add(ble_nus_t * p_nus, constble_nus_init_t * p_nus_init)
{
/**@snippet [S110 SoftDevice に独自の特性を追加]*/
ble_ gatts_char _md_tchar_md;
ble_gatts_attr_md_tcccd_md;
ble_gatts_attr_t attr_char_value;
ble_uuid_t ble_uuid;
ble_gatts_attr_md_tattr_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);
//上の行を次の行に変更します
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));
}
携帯電話がペアリングリクエストを送信すると、これはボードのイベント、つまりペアリングイベントになります。最後に、
caseBLE_GAP_EV T_DISCONNECTED:
APP_ERROR_CHECK (err_code);
break;
caseBLE_GATTS_EVT_SYS_ATTR_MISSING:
//システム属性は保存されていません。
err_code=sd_ble_gatts_sys_attr_set(m_conn_handle,
NULL, 0, 0);
APP_ERROR_CHECK(err_code);
Break;
default:
// 実装は必要ありません。
break;
}
}
設定する必要があるものはすべてここでセットアップは完了です。プログラムの実行後。携帯電話をボードに接続し、rx 特性値にアクセスします。この特性値は、Notify メソッドを通じてボード データを携帯電話に送信するために使用されるため、最初に携帯電話の通知ボタンをクリックしてボードの通知機能を有効にする必要があります。このボタンをクリックすると、パスワードを入力するためのペアリング ボックスがポップアップ表示されます。