Chapter 13
コミッショニング — QR コードから Fabric 参加まで
この章がなぜ必要なのか——最も失敗しやすく、最もユーザー体験を左右する部分.
ユーザーが Matter 機器に触れる最初の瞬間がコミッショニングである。 ここで失敗すれば返品される。
そして開発者にとっては、最も多くの要素が絡む工程でもある。 BLE・IPv6・mDNS・SPAKE2+・証明書検証・ネットワーク設定・NOC 発行—— どれか 1 つでも狂えば「見つかりません」で終わる。
この章では全手順を追い、それぞれで何が失敗しうるかを示す。
この章で使う既出の用語(定義は各リンク先). Matter(01 章 3 節)、コミッショニング(01 章 3 節)、ネットワーク(01 章 3 節)、ACL(02 章 4 節)、Administrator(02 章 5 節)、IPv6(02 章 1 節)、Node(02 章 2 節)、mDNS(03 章 4 節)、Wi-Fi(04 章 9 節)、BLE(05 章 1 節)、必要(05 章 5 節)、PASE(06 章 4 節)、SRP(06 章 2 節)、Fail-Safe(09 章 9 節)、Administer(11 章 8 節)、IPK(11 章 3 節)、パスコード(11 章 5 節)、盗聴(11 章 1 節)、総当たり(11 章 1 節)、署名(11 章 2 節)、証明書(11 章 5 節)、DAC(12 章 11 節)、メーカー(12 章 3 節)
1. 全体の流れ
[0] 機器がコミッショニング可能な状態で待つ(BLE / mDNS で広告)
↓
[1] ユーザーが QR コードをスキャン(または手動コードを入力)
↓ → passcode / discriminator / VID / PID を得る
[2] コントローラが機器を発見(BLE アドバタイズ or mDNS)
↓
[3] PASE セッション確立(SPAKE2+、passcode が根拠)
↓ ← ここから通信が暗号化される
[4] ArmFailSafe(失敗したら巻き戻すタイマーを開始)
↓
[5] デバイス認証(AttestationRequest → DAC / PAI / CD を検証)
↓
[6] CSRRequest → 機器が操作用鍵ペアを生成、CSR を返す
↓
[7] コントローラが NOC を発行
↓
[8] AddTrustedRootCertificate(Fabric のルート証明書を渡す)
↓
[9] AddNOC(NOC・ICAC・IPK・Admin Subject・Vendor ID を渡す)
↓ ← ここで Fabric が仮追加される
[10] ネットワーク設定(Wi-Fi 認証情報 or Thread Dataset)
↓
[11] 機器が運用ネットワークに参加
↓
[12] コントローラが運用ネットワーク上で機器を再発見(mDNS)
↓
[13] CASE セッション確立(NOC が根拠)
↓
[14] CommissioningComplete(Fail-Safe を解除、Fabric を確定)
↓
[15] BLE 切断、コミッショニング広告を停止[11]〜[13] が「トランスポートの切り替え」である. ここまでは BLE 上で話していたが、以降は Wi-Fi / Thread の IP 通信になる。 この切り替えが最も失敗しやすい。機器がネットワークに入れない、 入ったが mDNS で見つからない、といったトラブルがここで出る。
2. オンボーディングペイロード(QR コード)
QR コードには以下が 88 bit にパックされ、Base38 でエンコードされている。
| フィールド | ビット数 | 内容 |
|---|---|---|
| Version | 3 | ペイロードのバージョン(現在 0) |
| Vendor ID | 16 | メーカー |
| Product ID | 16 | 製品 |
| Custom Flow | 2 | 0=標準、1=ユーザー操作が必要、2=カスタム |
| Discovery Capabilities | 8 | ビットマスク(bit0=SoftAP, bit1=BLE, bit2=既存ネットワーク上, bit3=Wi-Fi PAF …) |
| Discriminator | 12 | 機器の絞り込み用(0〜4095) |
| Passcode | 27 | セットアップパスコード(1〜99999998) |
| Padding | 4 | 0 埋め |
| 合計 | 88 bit = 11 byte |
Base38 エンコード
| 文字集合 | 0-9, A-Z, -, . の 38 文字 |
|---|---|
| 3 byte → 5 文字 | \(38^5 = 79{,}235{,}168 > 2^{24}\) |
| 2 byte → 4 文字 | \(38^4 = 2{,}085{,}136 > 2^{16}\) |
| 1 byte → 2 文字 | \(38^2 = 1{,}444 > 2^{8}\) |
11 byte = 3 byte × 3 + 2 byte なので、5×3 + 4 = 19 文字。 先頭に MT: が付き、QR コード全体は 22 文字になる。
MT:Y.K9042C00KA0648G00ビットパックは LSB 側から詰める(リトルエンディアン的な順序)である。 実装するときは仕様の 5.1.3 節を精読すること。 バイト順を間違えると、まったく別の値としてデコードされる—— しかも「不正なコード」ではなく「別の有効な値」になるので、気づきにくい。
3. 手動ペアリングコード
QR コードが読めない場合(印刷が擦れた、カメラがない)のために、 数字だけのコードが併記される。
11 桁版(VID/PID なし)
| 位置 | 桁数 | 内容 | |
|---|---|---|---|
| 1 | 1 | `(VID/PID 有無) << 2 \ | (discriminator >> 10)` |
| 2〜6 | 5 | `((discriminator & 0x300) << 6) \ | (passcode & 0x3FFF)` |
| 7〜10 | 4 | passcode >> 14 | |
| 11 | 1 | Verhoeff チェックディジット |
21 桁版(VID/PID あり)
11 桁版の 10 桁目のあとに VID(5 桁)と PID(5 桁)が入り、最後にチェックディジット。
手動コードには Discriminator の上位 4 bit しか入らない. 12 bit のうち bit 8〜11 だけである(Short Discriminator)。 だから mDNS のサブタイプに
_S<n>(Short)と_L<n>(Long)の両方がある(06 章)。4 bit = 16 通りしかないので、周囲に同じ製品が複数あると絞り込めない。 QR コードの方が確実である。
Verhoeff チェックディジット
入力ミスを検出するアルゴリズム。単純な mod 10 より強力で、 隣接する桁の入れ替え(1234 → 1243)も検出できる。
二面体群 \(D_5\) の演算表・置換表・逆元表を使う。
人間が手で入力する前提なので、打ち間違いの検出が重要である. 最も多い入力ミスは「1 桁間違い」と「隣接 2 桁の入れ替え」である。 Verhoeff はこの両方を 100% 検出する。
4. Passcode の制約
| 項目 | 内容 |
|---|---|
| 範囲 | 1 〜 99,999,998 |
| ビット数 | 27 bit |
| 禁止値 | 00000000, 11111111, 22222222, …, 88888888, 99999999, 12345678, 87654321 |
禁止値がある理由. 推測されやすい値を排除するため。総当たりの最初に試される値である。
さらに重要: 個体ごとに違う値にすること。 SDK のデフォルト
20202021を製品に使うと、 誰でもその製品をコミッショニングできる。 製造時にランダムに生成し、SPAKE2+ の検証子を計算して焼き込む(12 章)。
5. PASE — SPAKE2+ によるセッション確立
コントローラ 機器
│ │
│──── PBKDFParamRequest ───────────>│ (ランダム、セッション ID)
│<─── PBKDFParamResponse ───────────│ (salt, iterations を返す)
│ │
│ passcode + salt + iterations │ (検証子 w0, L は保存済み)
│ → PBKDF2 → w0, w1 │
│ │
│──── Pake1 (X) ───────────────────>│
│<─── Pake2 (Y, cB) ────────────────│
│──── Pake3 (cA) ──────────────────>│
│<─── PakeFinished ─────────────────│
│ │
└──── 共有鍵を導出、以降は暗号化通信 ───┘| 要点 | 内容 |
|---|---|
| 機器はパスコードを保存しない | 検証子(w0, L)だけを持つ(11 章) |
| 盗聴者はオフライン総当たりできない | SPAKE2+ の性質 |
| 相互認証 | 双方が正しいパスコードを知っていることを確認 |
| PBKDF2 の反復回数 | 1000 以上(仕様の下限)。機器の計算能力とのトレードオフ |
PBKDF2 の反復回数が組み込み機器では効く. 反復回数が多いほど安全だが、低速な MCU では数秒かかる。 ユーザーは「反応がない」と感じる。
検証子を工場で事前計算しておけば、機器側は PBKDF2 を実行しなくてよい。 これが実装上の定石である(コントローラ側だけが PBKDF2 を回す)。
試行回数の制限
オンライン攻撃への対策は機器側の責任である. SPAKE2+ は「1 回の通信で 1 つのパスコードしか試せない」ことを保証するが、 何度も試すことは止められない。
仕様は、失敗が続いたらコミッショニングウィンドウを閉じることを求めている。 実装で必ず対応すること。 無制限に試行を許すと、27 bit のパスコードは破られうる。
6. Commissioning Window
機器がコミッショニング可能な状態でいる時間。
| 状態 | いつ |
|---|---|
| 初期状態 | 工場出荷時/ファクトリリセット後。自動的に開く |
| 追加のウィンドウ | 既存の管理者が AdministratorCommissioning クラスタで開く(14 章のマルチアドミン) |
| 項目 | 値 |
|---|---|
| 最小時間 | 3 分(180 秒) |
| 最大時間 | 15 分(900 秒) |
ウィンドウは必ず閉じること. 開きっぱなしだと、パスコードを知る者が誰でも参加できる。 タイムアウト、成功時、失敗回数超過——いずれでも確実に閉じる実装が必要である。
またウィンドウが開いている間は
_matterc._udpを広告するので、 閉じたら広告も止める。
7. ネットワーク設定
Network Commissioning クラスタ (0x0031) を使う。
Wi-Fi の場合
ScanNetworks ← 周囲の SSID を取得(任意)
AddOrUpdateWiFiNetwork ← SSID と credentials を渡す
ConnectNetwork ← 接続を指示Thread の場合
ScanNetworks ← 周囲の Thread ネットワークを取得(任意)
AddOrUpdateThreadNetwork ← Operational Dataset(TLV バイト列)を渡す([04 章](04_Thread.md#operational-dataset-thread-の-ネットワーク設定))
ConnectNetwork ← 参加を指示
ConnectNetworkの応答が返る前に、機器はネットワークに移動する. BLE の接続が切れることもある。 コントローラ側は「応答が来ないこと」を異常と決めつけず、 運用ネットワーク上での再発見に進む必要がある。ここの実装が甘いと「コミッショニングが 90% で止まる」症状になる。
8. NOC の発行
CSRRequest(nonce)
↓
機器: 操作用の鍵ペアを生成(P-256)、CSR を作成、DAC 秘密鍵で署名
↓
CSRResponse(NOCSRElements, AttestationSignature)
↓
コントローラ: 署名を検証 → CA に NOC の発行を依頼
↓
AddTrustedRootCertificate(RCAC)
AddNOC(NOC, ICAC, IPK, CaseAdminSubject, AdminVendorId)
↓
機器: Fabric を仮追加(Fail-Safe 下)| パラメータ | 内容 |
|---|---|
NOC | この機器の運用証明書(Node ID を含む) |
ICAC | 中間 CA(任意) |
IPK | Identity Protection Key(Fabric 共有) |
CaseAdminSubject | 管理者となる Node ID(または CAT) |
AdminVendorId | 管理者エコシステムの VID |
CaseAdminSubjectが最初の ACL エントリになる.AddNOCの直後、機器は「この Subject に Administer 権限を与える」ACL を自動生成する。 これがないと、コミッショニング直後に誰も機器を操作できなくなる(14 章)。
9. コミッショニングの種類
| 方式 | 内容 |
|---|---|
| 標準(Standard Commissioning Flow) | QR を読んで即座に開始できる |
| User-Intent | ユーザーが機器のボタンを押すなどの操作が必要 |
| Custom | メーカーのアプリなどで事前準備が必要 |
Custom Flow フィールド(QR ペイロードの 2 bit)で示される。
可能なかぎり標準フローにすべきである. ユーザーが「箱から出して QR を読むだけ」で終わるのが理想。 Custom Flow は「メーカーのアプリを先にインストールしてください」という 体験になり、Matter の利点を大きく損なう。
User Directed Commissioning (UDC)
テレビなどの機器が「私をコミッショニングしてください」と コントローラ側に働きかける方式。_matterd._udp を使う。
リモコンで QR コードを読むのが難しい機器(大型テレビなど)で使われる。
10. 落とし穴と診断
| 症状 | 疑うべきこと |
|---|---|
| BLE で見つからない | アドバタイズしていない/Discriminator の不一致/BLE の権限(スマホ側) |
| PASE で失敗 | passcode の不一致/検証子の計算ミス/salt・iterations の不整合 |
| Attestation で失敗 | 証明書チェーン/CD と DAC の VID/PID 不一致/PAA が信頼されていない |
| ネットワーク参加で失敗 | Wi-Fi パスワード/Thread Dataset の誤り/電波 |
| 参加後に見つからない | mDNS / SRP の問題(03 章・06 章)。最頻出 |
| CASE で失敗 | NOC の内容/時刻/IPK の不一致 |
| 90% で止まる | ConnectNetwork 後の再発見が失敗している |
| 2 回目以降のコミッショニングが失敗 | Fabric の上限に達している/前回の失敗が巻き戻っていない |
診断の順序
1. 機器のログで、どこまで進んだかを確認
↓
2. BLE で見つからない → 広告の確認、スマホ側の Bluetooth 権限
↓
3. PASE 失敗 → passcode / 検証子
↓
4. Attestation 失敗 → 証明書。開発中なら --paa-trust-store-path を確認
↓
5. ネットワーク参加失敗 → 認証情報、Dataset
↓
6. 再発見失敗 → dns-sd / ot-ctl srp server service([06 章](06_探索とメッセージング.md#見つからない-とき))
↓
7. CASE 失敗 → NOC、時刻、ACL# chip-tool でのコミッショニング例
# BLE + Wi-Fi
chip-tool pairing ble-wifi 1 <SSID> <PASSWORD> 20202021 3840
# BLE + Thread
chip-tool pairing ble-thread 1 hex:<dataset> 20202021 3840
# すでに同じネットワーク上にいる機器(開発時に便利)
chip-tool pairing onnetwork 1 20202021
# QR コードから
chip-tool pairing code 1 MT:Y.K9042C00KA0648G00
# 手動コードから
chip-tool pairing code 1 34970112332開発中は
pairing onnetworkが最速である. Linux 上のサンプルアプリなら BLE もネットワーク設定も要らない。 まずこれで動かし、次に BLE 経由を試すという順序が効率的である。
11. まとめ
- コミッショニングは 15 段階。BLE で始まり、PASE で暗号化し、証明書を検証し、 NOC を発行し、ネットワークに移し、CASE で確立して完了する。
- QR ペイロードは 88 bit を Base38 で 19 文字。
MT:を付けて 22 文字。 - 手動コードには Short Discriminator(4 bit)しか入らない。 Verhoeff チェックディジットで入力ミスを検出する。
- Passcode は個体ごとに違う値にする。禁止値を避ける。デフォルトのまま出荷しない。
- 機器はパスコードを保存せず、SPAKE2+ の検証子を持つ。 試行回数の制限は機器側の責任。
- Commissioning Window は 3〜15 分。必ず閉じる。
- 最も失敗するのは「ネットワーク参加後の再発見」。mDNS / SRP を疑う。
- Fail-Safe(09 章)が失敗時の巻き戻しを担う。