Chapter 14
運用時のセキュリティとマルチアドミン — CASE・ACL・Fabric
この章がなぜ必要なのか——「複数のエコシステムに同時対応」が Matter の売りだから.
Apple Home と Google Home に同じ電球を登録できる—— これは Matter の最大の差別化要因である。
だが技術的には難しい。互いを信頼しない複数の管理者が、 同じ機器を同時に管理するからである。
そして実装で最も多いバグの源でもある。 「1 つ目のエコシステムでは動くが 2 つ目で失敗する」は定番の症状である。
この章で使う既出の用語(定義は各リンク先). Matter(01 章 3 節)、コミッショニング(01 章 3 節)、セキュリティ(01 章 2 節)、ネットワーク(01 章 3 節)、ACL(02 章 4 節)、Administrator(02 章 5 節)、Cluster(02 章 2 節)、Endpoint(02 章 2 節)、Report(02 章 6 節)、マルチキャスト(03 章 3 節)、Wi-Fi(04 章 9 節)、必要(05 章 5 節)、Group(06 章 4 節)、PASE(06 章 4 節)、コミッショナ(06 章 1 節)、運用時(06 章 4 節)、NodeLabel(08 章 1 節)、Fail-Safe(09 章 9 節)、Administer(11 章 8 節)、IPK(11 章 3 節)、Manage(11 章 8 節)、Operate(11 章 8 節)、ProxyView(11 章 8 節)、乱数(11 章 2 節)、盗聴(11 章 1 節)、署名(11 章 2 節)、証明書(11 章 5 節)、鍵交換(11 章 2 節)、DAC(12 章 11 節)
1. CASE — 運用時のセッション確立
Certificate Authenticated Session Establishment。 双方が同じ Fabric の NOC を持っていることを相互に確認する。
イニシエータ レスポンダ
│ │
│──── Sigma1 ──────────────────────>│ 乱数、エフェメラル公開鍵、
│ │ 暗号化された宛先識別子
│<─── Sigma2 ───────────────────────│ 乱数、エフェメラル公開鍵、
│ │ 暗号化された NOC と署名
│──── Sigma3 ──────────────────────>│ 暗号化された NOC と署名
│<─── StatusReport (成功) ───────────│
│ │
└──── セッション鍵を導出、以降暗号化通信 ─┘| 特徴 | 内容 |
|---|---|
| SIGMA プロトコル | 相互認証付き鍵交換。ECDH(P-256)+ ECDSA 署名 |
| アイデンティティ保護 | 証明書は暗号化されて送られる。盗聴者に身元が漏れない |
| 前方秘匿性 | エフェメラル鍵を使うので、長期鍵が漏れても過去の通信は復号できない |
| IPK の役割 | 宛先識別子の生成に使われ、Fabric の一致を確認する |
なぜ証明書を暗号化するのか. 平文で NOC を送ると、盗聴者に「この家には Node ID 0x42 の機器がいる」と分かる。 プライバシーのため、Sigma2/Sigma3 の中身は暗号化される。
CASE Resumption
一度確立したセッションの情報を保持しておき、次回は短縮した手順で再確立する。
| 効果 | 内容 |
|---|---|
| ECDSA 署名検証を省略 | 組み込み機器では大きな節約(署名検証は重い) |
| ラウンドトリップの削減 | 応答が速い |
| 電池の節約 | 特に SED で効く |
P-256 の署名検証は、Cortex-M クラスの MCU で数十〜数百 ms かかる. ハードウェアアクセラレータがなければ、CASE 確立に 1 秒近くかかることもある。 Resumption の実装は、体感速度に直結する。
2. Fabric の構造
Fabric(1 つのエコシステムの管理ドメイン)
├── Root CA 証明書(RCAC) … この Fabric の信頼の根
├── Fabric ID(64 bit)
├── IPK(Identity Protection Key)
└── 所属する Node たち
└── 各 Node の NOC(Root CA が発行)機器側から見ると、Fabric ごとに以下を保持する。
| 保持するもの | サイズの目安 |
|---|---|
| RCAC | 数百 byte |
| ICAC(任意) | 数百 byte |
| NOC | 数百 byte |
| 操作用秘密鍵 | 32 byte(+ 保護のオーバーヘッド) |
| IPK | 16 byte |
| ACL エントリ | 数百 byte |
| グループ鍵 | 数十 byte × グループ数 |
| Fabric Label | 32 byte |
1 Fabric あたり 1〜2 KB は見ておく必要がある. 5 Fabric なら 5〜10 KB。RAM ではなく不揮発メモリを消費する。
SupportedFabricsを大きく宣言するなら、フラッシュの余裕を確保すること(17 章)。
Fabric Index
機器内部での Fabric の通し番号(1 から始まる 8 bit)。 Fabric-Scoped な属性(07 章)はこれで所属を区別する。
Fabric Index は機器のローカルな値である. 同じ Fabric でも、機器 A では Index 1、機器 B では Index 2 かもしれない。 グローバルな識別子ではないので、コントローラ間で共有してはいけない。
3. ACL — アクセス制御リスト
AccessControl クラスタ (0x001F) の ACL 属性。Fabric-Scoped である。
エントリの構造
| フィールド | 内容 |
|---|---|
| Privilege | View / ProxyView / Operate / Manage / Administer |
| AuthMode | PASE / CASE / Group |
| Subjects | 対象の Node ID のリスト(または CAT、Group ID)。空 = 全員 |
| Targets | 対象の {Cluster, Endpoint, DeviceType}。空 = すべて |
| FabricIndex | 所属 Fabric(自動設定) |
判定のルール
要求(Subject, 操作対象のパス, 必要な特権)が来る
↓
その Fabric の ACL エントリを順に見る
↓
以下をすべて満たすエントリが 1 つでもあれば許可:
- AuthMode が一致
- Subjects が空、または要求元の Node ID を含む
- Targets が空、または対象のパスに一致
- Privilege が必要な特権以上
↓
1 つもなければ UNSUPPORTED_ACCESS (0x7E)「拒否」のエントリは存在しない. 許可リストだけである。 だから ACL が空なら誰も何もできない。
コミッショニング時に
AddNOCのCaseAdminSubjectから 自動生成される 1 件目のエントリが、この状態を脱するための入口である(13 章)。
特権の階層
Administer ⊃ Manage ⊃ Operate ⊃ View上位は下位をすべて含む。ProxyView は View と同等の読み取りに使われる特殊な特権である。
CAT(CASE Authenticated Tag)
NOC の Subject に含められるタグ。個別の Node ID ではなく、 「このタグを持つ者」という単位で ACL を書ける。
ACL エントリ: { Privilege: Operate, AuthMode: CASE, Subjects: [CAT 0x0001_0001] }
→ CAT 0x0001_0001 を持つ NOC の保持者は誰でも Operate できる| 用途 | 内容 |
|---|---|
| 管理者の追加 | 新しいコントローラに同じ CAT の NOC を発行すれば、ACL を変えずに権限が付く |
| バージョン管理 | CAT の下位 16 bit がバージョン。古い版を無効化できる |
CAT は大規模なエコシステムで必須になる. 家族 5 人のスマホそれぞれに Node ID があるとき、 全機器の ACL に 5 つの Node ID を書くのは非現実的である。 CAT を 1 つ書いておけば、新しい端末は NOC の発行だけで参加できる。
4. マルチアドミン — 2 つ目のエコシステムを追加する
[すでに Apple Home にコミッショニング済みの電球]
↓
1. ユーザーが Apple Home で「他のプラットフォームに追加」を選ぶ
↓
2. Apple Home が AdministratorCommissioning.OpenCommissioningWindow を送る
- 新しい PAKE 検証子(新しい一時的な passcode に対応)
- タイムアウト(最大 15 分)
↓
3. 新しい QR コード(またはコード)が Apple Home の画面に表示される
↓
4. ユーザーが Google Home でそれを読む
↓
5. Google Home が PASE → 認証 → 自分の Fabric の NOC を発行して AddNOC
↓
6. 機器が 2 つ目の Fabric に所属する| コマンド | 内容 |
|---|---|
OpenCommissioningWindow | 新しい検証子を渡してウィンドウを開く(推奨) |
OpenBasicCommissioningWindow | 元の passcode でウィンドウを開く(機器の対応は任意) |
RevokeCommissioning | ウィンドウを閉じる |
OpenCommissioningWindowが推奨される理由. 元の passcode(QR コードに印刷されている)を再利用すると、 箱や本体のラベルを見た人が誰でも参加できる。新しい一時的な検証子を使えば、その場で表示された値を知る者だけが参加できる。 時間制限もあるので、より安全である。
Enhanced Multi-Admin(1.4 以降)
QR コードの手動読み取りを不要にし、エコシステム間で直接連携して機器を共有する仕組み。 ユーザー体験の改善が目的である。対応は各エコシステムの実装次第となる。
5. Fabric の管理
| コマンド/属性 | 内容 |
|---|---|
OperationalCredentials.Fabrics | 所属している Fabric の一覧(Fabric-Sensitive) |
OperationalCredentials.SupportedFabrics | 対応可能な最大数 |
OperationalCredentials.CommissionedFabrics | 現在の所属数 |
UpdateFabricLabel | ユーザー向けのラベルを設定 |
RemoveFabric | Fabric から離脱 |
Fabrics属性は Fabric-Sensitive である. Apple Home から読むと、Google Home の Fabric の詳細(ラベルなど)は隠される。 「他にいくつ所属しているか」は分かるが、中身は見えない——これが仕様の意図である。
RemoveFabric の注意
RemoveFabric(fabricIndex)
↓
その Fabric の NOC・鍵・ACL・グループ鍵・サブスクリプションをすべて削除
↓
所属 Fabric が 0 になったら → ファクトリリセット相当の状態に戻る自分自身の Fabric を削除すると、応答が返らないことがある. セッションが即座に無効になるためである。 コントローラ側は「応答なし」を成功として扱う必要がある。
6. グループ通信のセキュリティ
グループコマンド(09 章)はマルチキャストで、CASE セッションを使わない。 代わりにグループ鍵で保護する。
Group Key Management クラスタ
├── GroupKeySet(鍵の集合。Epoch キーを 3 世代まで持てる)
└── GroupKeyMap(Group ID ↔ GroupKeySet の対応)| 特徴 | 内容 |
|---|---|
| Fabric-Scoped | Fabric ごとに独立 |
| Epoch キー | 世代交代できる。古い鍵と新しい鍵を並行して受け入れる期間がある |
| 対称鍵 | グループの全メンバーが同じ鍵を持つ |
グループ鍵は「グループの誰か 1 台が漏れたら全部漏れる」構造である. 対称鍵なので原理的にこうなる。 だからグループ通信は重要度の低い操作に限るのが設計上の原則である。 ドアロックの解錠をグループコマンドで行うべきではない。
Epoch キーのローテーションは、この弱さを緩和するための仕組みである。
7. ファクトリリセット
| トリガ | 例 |
|---|---|
| 物理ボタンの長押し | 最も一般的 |
| 全 Fabric の削除 | RemoveFabric の結果 |
| 特定の手順 | 電源の入切を N 回など |
消すべきもの:
- ☐ すべての Fabric(NOC、RCAC、ICAC、操作用秘密鍵、IPK)
- ☐ ACL
- ☐ グループ鍵
- ☐ バインディング
- ☐ ネットワーク認証情報(Wi-Fi パスワード、Thread Dataset)
- ☐ サブスクリプション情報
- ☐ ユーザー設定(NodeLabel など)
消してはいけないもの:
- DAC / PAI / CD と DAC 秘密鍵(工場データ)
- VID / PID / シリアル番号
- SPAKE2+ 検証子(元の passcode に対応するもの)
中古品・返品されて再販される機器で、これが決定的に重要になる. 前の持ち主の Wi-Fi パスワードが残っていたら重大な事故である。
ファクトリリセットの完全性は、認証テストでも確認される。 「消したつもりで消えていない」を防ぐため、リセット後に実際にフラッシュを ダンプして確認するテストを開発工程に入れるべきである。
8. 落とし穴
| 落とし穴 | 内容 |
|---|---|
| ACL の設定漏れ | UNSUPPORTED_ACCESS (0x7E) の主因。最頻出 |
| Fabric-Scoped の実装ミス | 他 Fabric の設定を消す・見せてしまう |
| Fabric 数の見積り不足 | 2〜3 個目で RESOURCE_EXHAUSTED |
| 不揮発メモリの不足 | Fabric 追加で書き込み失敗 |
| CASE Resumption 未実装 | 再接続が遅い(特に電池機器) |
| ウィンドウを閉じ忘れる | 誰でも参加できる状態が残る |
RemoveFabric の応答待ち | 自分自身を削除すると応答が来ない |
| ファクトリリセットの不完全性 | 前の持ち主の情報が残る |
| グループ鍵の Epoch 管理ミス | 鍵交代時に通信が途切れる |
| 時刻のずれ | 証明書の有効期限判定に影響しうる |
「1 つ目は動くが 2 つ目で失敗する」の診断.
CommissionedFabricsとSupportedFabricsを読む → 上限に達していないか- 不揮発メモリの空きを確認 → 書き込み失敗していないか
- Fabric-Scoped 属性の実装を確認 → 1 つ目の設定を上書きしていないか
- ACL を読む → 2 つ目の Fabric のエントリが作られているか
- Fail-Safe の巻き戻しを確認 → 前回の失敗が残っていないか
開発中は必ず 3 つ以上の Fabric でテストすること。 chip-tool は
--commissioner-nameで複数の Fabric を扱える。
# 2 つ目の Fabric として追加する(chip-tool)
# まず既存の管理者としてウィンドウを開く
chip-tool pairing open-commissioning-window 1 1 300 1000 3840
# → 表示された manual code / QR で別のコミッショナから参加
chip-tool --commissioner-name beta pairing code 1 <code>
# Fabric の一覧を確認
chip-tool operationalcredentials read fabrics 1 0
chip-tool operationalcredentials read commissioned-fabrics 1 0
# ACL を確認
chip-tool accesscontrol read acl 1 09. まとめ
- CASE が運用時のセッション。SIGMA ベースで、相互認証・前方秘匿性・ アイデンティティ保護を持つ。Resumption の実装が体感速度を左右する。
- Fabric はエコシステムの管理ドメイン。機器は複数所属でき、 それぞれに NOC・鍵・ACL・グループ鍵を持つ。1 つあたり 1〜2 KB の不揮発メモリ。
- ACL は許可リストのみ。空なら誰も何もできない。
UNSUPPORTED_ACCESS(0x7E) が出たらここを疑う。 - CAT で「タグ単位」の権限付与ができる。大規模エコシステムでは必須。
- マルチアドミンは
OpenCommissioningWindowで新しい一時検証子を使うのが安全。 - グループ通信は対称鍵なので、重要な操作には使わない。
- ファクトリリセットの完全性は、中古流通を考えると極めて重要。
- 開発中は必ず 3 つ以上の Fabric でテストする。