ATECC608A-TNGTLS検証(Azure IoT DPS接続テスト)(ATECC608A-TNGTLS Azure IoT DPS connection test)

#はじめに#

Azure,AWSなどのIoTクラウドサービスへのデバイスのセキュアな接続は、TLS通信を使って行いたいと考える。
しかし、不特定の場所にばらまかれることが想定されるデバイスに、クラウドとの接続を行うためのデバイス証明書と秘密鍵をどう安全に置くかについて、現状多くの課題がある。

一つのアプローチとして、デバイスに専用のデバイス証明書と秘密鍵を格納できるデバイスを設置することが以前より推奨されている。
Azure Sphereも同様に証明書ベースの認証を安全に行うための秘密鍵の秘匿機能を持っている。

何度かテストしている、Microchip ATECC608Aは秘密鍵の秘匿という点で専用に設計されたデバイスになる。

#前回までのあらすじ#
過去に[セキュアなIoTデバイス通信をやってみた(Azure IoT 接続編‐DPSプロビジョニング)](https://qiita.com/kmitsu76/items/0cf4bf0c6fd1af4ce26b)で、ATECC608Aを搭載したESP32でAzure DPSへ接続し、デバイス証明書を登録してAzure IoTへ接続する準備を行うテスト（プロビジョニング）を行った。

この際、
１、ユーザー自身でCAを作成し、CA証明書をAzure DPS,Azure IoTに登録しておく
２、デバイス毎にユーザーCAの秘密鍵で署名し、デバイス証明書を作成しデバイスに書き戻す
３、デバイスからAzure DPSに接続してデバイスの証明書をAzure IoTに登録する
４、通信開始

という大まかな流れを踏んでいた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/3ccd1e9b-61c1-8bb5-5b62-4173f9a2a345.png)

ここで問題になるのは、ユーザー用意のCA自体、OpenSSLのコマンドで簡単に作れるが、運用となると秘密鍵の安全な保管、漏洩に注意しなければならない。
また、デバイス毎にデバイス証明書を作成しデバイスに書き戻す手間もかかってしまう。

もっとお手軽にできないかというアイデアで、ATECC608Aに事前にメーカーのCAを使い証明書を書き込んで出荷してくれるサービスが"Trust and Go"である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/c12cab6e-27fe-7cda-ca27-1c4e4ca92749.png)

イメージはメーカーが出荷時に、ATECC608Aとともに書き込まれている証明書の台帳を合わせて出荷してくれ、ユーザーはその台帳を使って証明書を事前にAzureに書き込んでおけるというイメージになる。

手軽にクラウド接続をセキュアにするにはよさそうなので、これを試してみる。

今回の記事に関連するソースコードは下記にて公開中。
[kmwebnet/ECC608-TNG-Azure-DPS-Connect](https://github.com/kmwebnet/ECC608-TNG-Azure-DPS-Connect)

#ATECC608AのTrust and Go#
ATECC608Aは16個のスロットの役割、権限を個別に設定できるConfigを設定し使用できるようになる。
また証明書は定義ファイルを生成し、デバイスとセットで使用する。
しかしこの設定と生成が難解なので、事前に設定されたデバイスとして販売されている。
TrustFLEX,TrustCUSTOMという姉妹品もあるが、特にTrust and Goはチップを購入した段階で書き込まれている証明書の台帳が入手できるらしい。

[Microchip Direct](https://www.microchipdirect.com/)でTrust and Goを購入してみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/3993dc08-7575-b049-57a5-7e2bdc02928d.png)

このOrder History画面から、"Download Manifest"をクリックすると、jsonのファイルがダウンロードできる。
このJSON のファイルの中にオーダー分の証明書が収まっている形。

#Azure接続のシナリオ#
Trust and Goを使うことで、下記作業がなくなり簡略化される。
１、ユーザー自身でCAを作成し、CA証明書をAzure DPS,Azure IoTに登録しておく
２、デバイス毎にユーザーCAの秘密鍵で署名し、デバイス証明書を作成しデバイスに書き戻す

今回の検証を行ったGitレポジトリをクローンする。

```
git clone --recursive https://github.com/kmwebnet/ECC608-TNG-Azure-DPS-Connect.git
cd ECC608-TNG-Azure-DPS-Connect
```

まず、台帳ファイル（ダウンロードしたJSONファイル）から証明書を抜き出すスクリプトを実行し、certs/フォルダ内にPEMファイルとして保存する。

```
pip install python-jose[cryptography]
manifestdecoder.py --manifest <マニフェストファイル>
```

Azure IoT DPSを構築し、IDスコープを後ほど使うためメモしておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/cd12886d-0e96-1bac-bdda-47ea7d1a941d.png)

Azure IoT Hub をF1　フリーインスタンスで作成し、IoT Hubへのリンクを設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/17cda3e5-4a6e-92bb-3f04-2857a6d2c68d.png)

Azure DPSの、「登録を管理します」->「個別登録の追加」から先ほど用意したcerts/内の証明書をアップしていく。
デバイスIDはデバイス証明書のコモンネームと同じにしてみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/ff97cd64-0727-adde-b0ab-17cd4a993f34.png)


登録した時点では、状態が"Unassigned"になっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/b64a64a0-8cee-3429-a894-c1298efdd0df.png)

サンプルファイルを動作させると以下の通り、Azure DPSへの通信から、リンク済みのIoT HubのURLが返され、新たに接続ハンドルを作り直し、Azure IoTへ接続する動作を行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/92c96ee8-1e22-dcf8-8ad2-79cb6dfea8ae.png)

Azure DPSの登録の詳細が更新され、状態が"Assigned"に変更された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/f9abfe24-ad56-40f1-f5e8-af810483a84e.png)

Azure IoT側にも、IoTデバイスとして登録された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/8f2d0453-339b-7056-d11b-151dae8de6ca.png)

#まとめ#
クラウドとの接続をまず守りたいが、CA構築と運用が難しい場合に、簡単に使えるソリューションであることが分かった。
特にデバイスを設計してPoCをやる段階からこのくらいのセキュリティは実装する前提で考えたほうが、少ないデバイスの資源の中、セキュリティ考慮での開発の後戻りを防げるかもしれない。