Azure IoT Centralのデバイス認証

Azure IoT Centralのデバイス認証を何回も何回も何回も聞かれて都度説明するのが面倒なので、徹底的に調べて記事にしました。

# 結論

* デバイス認証の仕組みは**SAS**、**X.509**、**TPM**の3種類が使える。
* **SAS**と**X.509**は1デバイスずつと一度に複数デバイスを許可することができる。
* **TPM**は1デバイスずつ許可。一度に複数デバイスを許可はできない。
* 一度に複数デバイス許可では、認証時に自動的にAzure IoT Central上のデバイスを作成させることができる。
* 設定画面は**デバイス > {device} > 接続**と**アクセス許可 > デバイス接続のグループ**の2画面ある。きちんと理解して適切な画面を使う。

# Azure IoT Central上のデバイス認証設定画面

`デバイス > {device} > 接続`（`Devices > {device} > Connect`）と`アクセス許可 > デバイス接続のグループ`（`Permissions > Device connection groups`）の2箇所あります。

日本語表示：
<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/709b28a9-2127-1b60-9cff-35d9ae186c1b.png">
英語表示：
<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/5982e559-2717-7cda-7529-ccd4bda80874.png">

認証の仕組み（SAS、X.509、TPM）と許可の数（個別、グループ）で表にするとこのようになります。

||個別 - individual|グループ - group|
|:--|:--|:--|
|SAS|[デバイスSAS]<br>A3-1|[グループSAS]<br>B1<br>(A1)|
|X.509|[デバイスX.509]<br>A3-2|[グループX.509]<br>B2<br>(A2)|
|TPM|[デバイスTPM]<br>A3-3|-|

A1はB1と同じですが、グループSASキーから計算で生成できるデバイスSASキーを手早く確認したいときに見ることがあります。（グループSASキー？デバイスSASキー？何のこと？と思うでしょうか、あまり気にせず読み進んでください。）

A2はB2と同じです。グループX.509を複数登録しているときに見るかもしれませんが、レアケースなのでA2は無視して良いです。

# SAS

Azure IoT Centralのデバイス認証で使う**SAS**は、**リソースURI**と**有効期限**を**SASキー**で署名した**SASトークン**で認証する方式のことです。（詳しくは[こちら](https://learn.microsoft.com/ja-jp/azure/iot-hub/iot-hub-dev-guide-sas?WT.mc_id=AZ-MVP-5002686#sas-token-structure)。）
漏れないようにする情報はSASキーとSASトークンです。SASトークンは、短い有効期限で運用して、漏れても被害が起きにくいようにします。

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/158a8be8-483d-2859-0ad1-b6a847323575.png">

## デバイスSAS

**デバイスSASによる認証**では、**デバイスSASキー**をデバイスに保持しておき、Azure IoT Centralと通信する際に**デバイスSASキー**から**SASトークン**を算出して接続、認証します。

デバイスSASキーはAzure IoT Centralから発行されるものではありません。```echo `openssl rand -base64 64 | tr -d '\n'` ```のように自らデバイスSASキーを生成してAzure IoT Centralに登録します。（試した記事は[こちら](https://matsujirushi.hatenablog.jp/entry/2022/10/06/115654)。）

1. デバイスSASキーを生成（例えば、`openssl rand`）
1. デバイスSASキーをA3-1. Shared access signature(SAS)画面に登録
1. デバイスSASキーをデバイスに保持
1. Azure IoT Central接続時にSASトークンで認証（リソースURI、有効期限、デバイスSASキーから算出）

## グループSAS

**グループSASによる認証**では、Azure IoT Centralが発行した**グループSASキー**を用いて認証します。デバイスに（グループSASキーではなく）**デバイスSASキー**を保持しておき、デバイスSASと同様に接続、認証します。

グループSASキーはAzure IoT Centralから発行されます。
さて、デバイスSASキーはどこから手に入れるのでしょうか？
**デバイスSASキ**ーは、**グループSASキー**と**デバイスID**から算出できます。また、（Azure IoT Centralでデバイスを作成すれば）Azure IoT CentralのA1. Shared access signature(SAS)画面でも確認できます。

<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/a88fb0c6-b596-aa24-d6be-bab0303fa50e.png">

[コードによる算出](https://github.com/SeeedJP/wioterminal-aziot-example/blob/seeed-master/src/Signature.cpp#L40)も可能なので、独自にデバイスSASキー生成ツールを作ることもできます。ただし、デバイスにグループSASキーを保持しておき、必要な都度、デバイスSASキーを生成する仕組みにはしないでください。グループSASキーが漏れて自由にデバイスSASキーを作られてしまう可能性があるからです。

1. グループSASキーをB1. Shared access signature(SAS)画面から取得
1. デバイスSASキーを算出（グループSASキー、デバイスIDから算出）
1. デバイスSASキーをデバイスに保持
1. Azure IoT Central接続時にSASトークンで認証（リソースURI、有効期限、デバイスSASキーから算出）

# X.509

Azure IoT Centralに接続するTLS（Transport Layer Security）で、クライアント証明書として**デバイス証明書**を提示して認証する方式のことです。（詳しくは[こちら](https://learn.microsoft.com/ja-jp/azure/iot-hub/iot-hub-x509ca-concept?WT.mc_id=AZ-MVP-5002686)。）

> TLSとPKIについては、[書籍「暗号と認証 最強の指南書」](https://bookplus.nikkei.com/atcl/catalog/18/270540/)で理解が深まりました。おすすめ。

漏れないようにする情報は**デバイス秘密キー**です。

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/214f3685-2301-029a-8bbb-34daef283962.png">

## デバイスX.509

**デバイスX.509による認証**では、**デバイス証明書**と**デバイス秘密キー**をデバイスに保持しておき、Azure IoT Centralと通信する際の**TLSの相互認証**でクライアント証明書に**デバイス証明書**を提示して認証します。

デバイス証明書とデバイス秘密キーはAzure IoT Centralから発行されるものではありません。`openssl ecparam`などで自ら生成します。そして、デバイス証明書はAzure IoT Centralに登録します。（試した記事は[こちら](https://matsujirushi.hatenablog.jp/entry/2022/09/26/205631)。）

1. デバイス証明書とデバイス秘密キーを生成（例えば、`openssl ecparam`+`openssl req`）
1. デバイス証明書をA3-2. 証明書(X.509)画面に登録
1. デバイス証明書、デバイス秘密キーをデバイスに保持
1. Azure IoT Central接続時にTLSの相互認証で認証（デバイス証明書、デバイス秘密キー）

## グループX.509

デバイスX.509と同様ですが、Azure IoT Centralへ登録する証明書がデバイス証明書ではなく、デバイス証明書の署名者の証明書（CA証明書）です。（試した記事は[こちら](https://matsujirushi.hatenablog.jp/entry/2022/10/15/201958)と[こちら](https://matsujirushi.hatenablog.jp/entry/2022/10/21/205331)。）

1. CA証明書とCA秘密キーを生成（例えば、`./certGen.sh create_root_and_intermediate`）
1. 署名したデバイス証明書とデバイス秘密キーを生成（例えば、`./certGen.sh create_device_certificate_from_intermediate`）
1. CA証明書をB2. 証明書(X.509)画面に登録
1. デバイス証明書、デバイス秘密キーをデバイスに保持
1. Azure IoT Central接続時にTLSの相互認証で認証（デバイス証明書、デバイス秘密キー）

# デバイスTPM

WIP
（まだ試していないので、、、試した後に書く。）
（詳しくは[こちら](https://learn.microsoft.com/ja-jp/azure/iot-dps/concepts-tpm-attestation?WT.mc_id=AZ-MVP-5002686)。）

# お願い

読んでみても「意味わからねー」という方は、お気軽にコメントください。
（みんなが悩まないように、記事を改善したいので。）

# 参考リンク

* [IoT Central のデバイス認証の概念  / Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/iot-central/core/concepts-device-authentication)
* [SASトークン構造 / Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/iot-hub/iot-hub-dev-guide-sas?WT.mc_id=AZ-MVP-5002686#sas-token-structure)
* [ComputeDerivedSymmetricKeyコード / SeeedJP](https://github.com/SeeedJP/wioterminal-aziot-example/blob/seeed-master/src/Signature.cpp#L40)
* [IoT での X.509 CA 証明書の使用方法を理解する / Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/iot-hub/iot-hub-x509ca-concept?WT.mc_id=AZ-MVP-5002686)
* [TPM の構成証明 / Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/iot-dps/concepts-tpm-attestation?WT.mc_id=AZ-MVP-5002686)
* [暗号と認証 最強の指南書 / 日経BOOKプラス](https://bookplus.nikkei.com/atcl/catalog/18/270540/)
* [Azure_IoT_Central_ESP32をSeeed Studio XIAO ESP32C3で動かしてみた（個別SAS） / matsujirushi](https://matsujirushi.hatenablog.jp/entry/2022/10/06/115654)
* [Azure_IoT_Central_ESP32をSeeed Studio XIAO ESP32C3で動かしてみた（グループSAS） / matsujirushi](https://matsujirushi.hatenablog.jp/entry/2022/09/24/212238)
* [Azure_IoT_Central_ESP32をSeeed Studio XIAO ESP32C3で動かしてみた（個別X.509） / matsujirushi](https://matsujirushi.hatenablog.jp/entry/2022/09/26/205631)
* [Azure_IoT_Central_ESP32をSeeed Studio XIAO ESP32C3で動かしてみた（グループX.509） / matsujirushi](https://matsujirushi.hatenablog.jp/entry/2022/10/15/201958)
* [Azure_IoT_Central_ESP32をSeeed Studio XIAO ESP32C3で動かしてみた（グループX.509 その2） / matsujirushi](https://matsujirushi.hatenablog.jp/entry/2022/10/21/205331)