Tech

BLEのペアリングをWiresharkでキャプチャしながら学ぶ

投稿日:

はじめに

BLEはペアリングすることなく通信することができますが、その状態ではデバイスの付近にいれば誰でも通信できてしまいます。そのため、製品化する場合には、ほとんどのケースでペアリングを実装する必要があります。
例えば、スマートウォッチでは、初回起動時にスマホとのペアリングをすることで、他者からアクセスできないようにしています。

BLEの開発をしていると、ペアリングに関する部分は低レイヤーなので、アプリケーションレベルで気にすることは少ないのですが、今回は実際にどのようにペアリングが行われているのかを掘り下げてみたいと思い、Wiresharkでキャプチャーしながら学ぶことにしました。

ペアリングとボンディング

Bluetoothのデバイスを使用するとき、ユーザはペアリングをして、その後はペアリング作業なしに接続できるようにしたいと思います。このようにするためには、Bluetoothの仕様上、「ボンディング」が必要になります。
ペアリングとは、デバイスとの暗号化通信を行うための鍵を交換すること自体を言います。そして、ボンディングとは、ペアリングを実施し、生成された鍵を保存することで、以降の暗号化通信ができるようにしておくことを言います。
今回は、ボンディングも行うケースとなります。

暗号化はキャラクタリスティック単位

BLEでは、暗号化はキャラクタリスティックの属性として設定します。そのため、1つのサービス内で、公開されたキャラクタリスティックと、暗号化されたキャラクタリスティックを混在させることができます。

ペアリングしていない状態で暗号化されたキャラクタリスティックにアクセスすると、 Error Code: Insufficient Encryption (0x0f) というエラーがレスポンスされます。
実際にWiresharkで見てみるとこのようになります。

ちなみに、今回は次のような構成になっています。

デバイス ペアリング時の役割 BLEの役割 Wireshark上の表示 IO Capability
iPhone イニシエータ セントラル MACアドレス(ぼかしています) DisplayKeyboard
Raspberry Pi レスポンダ ペリフェラル localhost() DisplayOnly

Raspberry Pi側は、次のような構成になっています。

  • BlueZ
    Bluetooth通信の窓口となっているモジュールで、デーモンとして動いています。bluezと各種ソフトウェアは、DBusを経由して対話します。
    実際のペアリングや、ペアリングで交換した鍵の保存などもBlueZが行っています。
  • bt-agent
    IO Capabilityの指定や、ペアリング時に生成されたPasskeyの表示などを行います。起動させると、BlueZ側にAgentとして登録されることで動作します。BlueZとの対話はDBusを使用します。
  • キャラクタリスティック用のプログラム
    暗号化属性を与えたキャラクタリスティックのプログラムを用意します。BlueZとはDBusで対話するため、Pythonなどで実装可能で、キャラクタリスティックのflagsに encrypt-read もしくは encrypt-write を指定します。

ペアリングの流れ

BLEでは、暗号化通信に使用する暗号鍵をペアリングで交換し、以降の通信で使います。この暗号鍵のことをLTK(Long Term Key)と呼び、ここからはLTKを交換するためのペアリングの流れについて説明します。
ペアリングは次の図の流れで行われます。

ペアリングリクエストを送った方がイニシエータとなり、その相手がレスポンダとなります。
イニシエータが暗号化されたキャラクタリスティックにアクセスすると、先ほどの通りエラーがレスポンスされますが、その際にセキュリティリクエストもレスポンスされます。
それを受けて、イニシエータ側はペアリングれリクエストを行います。

BLEペアリングには、次の2種類があります。

  • LE legacy pairing
  • LE Secure Connections

この2つの違いは、LTK(LongTerm Key)を無線通信上で交換するか否かになります。Legacy Pairingでは最初にSTK(Short Term Key)を生成し、STKによる暗号化通信でLTKを無線通信で交換します。
このため、legacy pairingではLTKが盗聴される可能性があります。しかし、Secure Connectionsであれば、LTKはPasskey認証などによって各デバイス上で生成されるため、無線通信上で交換する必要がなく、安全です。
今回は、Secure Connectionsの流れを見ていきたいと思います。

セキュリティリクエスト

一番初めにレスポンダからセキュリティの要求が行われます。この通信は任意ですが、ペアリングリクエストと似たようなパラメータ構成となっています。

ペアリングリクエスト・レスポンス

イニシエータからレスポンダにペアリングリクエストが送られることで、ペアリングが開始します。ここで、IO Capabilityをリクエスト時に送信し、レスポンダ側も自身のIO Capabilityをレスポンスします。
IO Capabilityとは、デバイスのもつ入手出力の特性のことで、主に次のように設定します。

  • DisplayOnly もしくは DisplayYesNo: Passkeyの表示によるペアリング
    例: スマートウォッチなど
  • KeyboardOnly もしくは KeyboardDisplay: キーボード入力によるペアリング
    例: スマホ、キーボードなど
  • NoInputNoOutput
    例: マウスなど、ディスプレイもキーボードも持たないデバイス

今回、イニシエータのiPhoneはKeyboard Display、レスポンダのRaspberry PiはDisplay Onlyとしています。この場合、iPhone側には次のようなPasskey入力画面が表示され、Raspberry Pi側に出力された6桁のPasskeyを入力します。

Raspberry Pi側では、bt-agentを立ち上げている状態にしておくと、ターミナルにPasskeyが出力されるので、これをiPhoneで入力します。
bt-agentは先ほど説明した通り、デーモンで動いているBlueZと対話し、IO Capabilityの指定と、生成されたPasskeyの表示を行います。
Passkeyの生成や、ペアリング自体はBlueZ側が行うので、あくまでbt-agentはDBusを経由してBlueZと対話するのみとなります。

Wiresharkで見てみると、次のようになります。
まずは、ペアリングリクエストです。
ここで、 Bonding Flagsがありますが、ここを 0x1 (Bonding)にすると、この後生成するLTK(Long Term Key)をお互いに保存しておき、次回以降ペアリングが不要となります。
レスポンスは次のようになります。
レスポンダであるRaspberry PiのIO Capabilityは、Dsiplay Onlyに設定しました。この組み合わせの場合は、先ほど説明したように、Raspberry Piで表示されたPasskeyを、iPhoneに入力することで認証します。
お互いのIO Capabilityの組み合わせによって、認証時のユーザによる作業が決定します。

Passkeyの検証

正しくPasskeyが入力されたかを検証します。検証用の公開鍵の交換、Passkeyの検証、DH Key検証の3ステップで行われます。
先ほどの通り、PasskeyからLTKを生成できるので、Passkeyの検証を通過すれば、LTKが有効であることが確認され、ペアリングが完了します。

生成されたLTKは、Raspberry PiではBlueZに保存されます。以下のコマンドを使うと、実際にペアリングされたデバイスを確認することができます。

iPhoneでは、設定画面のBluetoothでペアリング済みデバイスとして表示されます。

キャラクタリスティックとの暗号化通信

ペアリングが完了すると、暗号化されたキャラクタリスティックを読み込むことができました。
一度交換したLTKは、いずれかのデバイスがペアリング解除を行うまで使用できます。

おまけ

Raspberry PiでWiresharkを使うと、Bluetoothのパケットをキャプチャーすることができます。導入は非常に簡単です。

これでWiresharkが起動するので、 bluetooth0 を選択すると、Bluetoothの通信をキャプチャすることができます。

BLEはプロトコルスタックで、実際には様々なプロトコルの通信が行われているため、プロトコルによるフィルタリングは便利でした。
例えば、SMPプロトコルのみ表示するには、 btsmp で絞り込みます。また、ATTプロトコルを絞り込むには btatt を指定します。
その他にも、Bluetoothのフィルター条件がたくさんあるので、右側の「書式…」ボタンを押せば、他のフィルターも探すことができます。

さいごに

次回はBlueZやbluetoothctlの仕組みについて深堀していきたいと思います!

おすすめ書籍

Bluetooth Low Energyをはじめよう (Make:PROJECTS) iOS×BLE Core Bluetoothプログラミング

blog-page_footer_336




blog-page_footer_336




-Tech
-,

執筆者:


comment

メールアドレスが公開されることはありません。

CAPTCHA


関連記事

Bluetooth Low Energy(BLE)とは? Bluetoothの開発が初めての人向け!

1 はじめに2 Bluetoothの規格2.1 Bluetooth Classic2.2 BLE(Bluetooth Low Energy)3 BLEの役割4 サービスとキャラクタリスティック4.1 ...

BlueZとは? bluetoothctlとPythonから使用する方法を紹介!

1 はじめに2 BlueZとは?2.1 D-Busとは?3 bluetoothctlでのペアリング3.1 ペアリング4 Pythonでの実装4.1 bluezeroでのペアリング実装5 さいごに6 お ...

iOS13ダークモード対応

1 はじめに2 一時しのぎ3 実装3.1 UI Element Colors3.2 Color Set3.3 コードで描きたい3.4 カスタムのカラーを定義する3.5 画像をモードで動的に変更したい4 ...

【Unity】Animatorを利用するための基本知識

1 はじめに2 Animator3 Stateの追加4 Transitionの追加5 パラメーターの作成6 さいごに7 おすすめ書籍 はじめに こんにちはsuzukiです。今回はunityのanima ...

ReactNative開発のスタート、シミュレータでのデバッグ

1 はじめに2 改めてシミュレータの起動3 表示内容を変更してみる3.1 App.js3.2 表示テキストの変更3.3 シミュレータの更新「command + R」4 デバッグメニュー4.1 Real ...

フォロー

blog-page_side_responsive

2021年8月
1234567
891011121314
15161718192021
22232425262728
293031  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。