チュートリアル:登録グループを使って複数の X.509 デバイスをプロビジョニングする
このチュートリアルでは、認証に X.509 証明書を使用する一連の IoT デバイスをまとめてプロビジョニングする方法を説明します。 Azure IoT SDK のサンプル デバイス コードは、X.509 デバイスのプロビジョニングをシミュレートするために開発用マシンで実行されます。 実際のデバイスでは、デバイス コードはデプロイされて IoT デバイスから実行されます。
Azure IoT Hub Device Provisioning Service では、デバイスのプロビジョニングについて 2 種類の登録をサポートしています。
- 登録グループ:複数の関連するデバイスを登録するために使用します。 このチュートリアルでは、登録グループを使用したプロビジョニングについて説明します。
- 個別登録: 単一デバイスを登録するために使用します。
Azure IoT Hub Device Provisioning Service では、デバイスをプロビジョニングするための 3 つの形式の認証がサポートされています。
- X.509 クライアント証明書 - このチュートリアルでは、X.509 証明書の構成証明について説明します
- トラステッド プラットフォーム モジュール (TPM)
- 対称キー
本番環境のシナリオでは、ハードウェア セキュリティ モジュール (HSM) は、デバイス シークレットをハードウェアベースで安全に格納するために使用されます。 対称キー、X.509 証明書、または TPM の構成証明と HSM を併用すると、シークレットの安全なストレージを実現できます。 デバイス シークレットのハードウェアベースのストレージは、デバイス証明書の秘密キーなどの機密情報を保護するためにお勧めします。
このチュートリアルの目標は次のとおりです。
- 証明書の信頼の連鎖を作成して、X.509 証明書を使用する一連のデバイスを整理する。
- 証明書チェーンを使用する新しいグループ登録を作成する。
- 開発環境を設定する。
- Azure IoT device SDK のサンプル コードを使って、証明書チェーンを使っているデバイスをプロビジョニングする。
前提条件
Azure サブスクリプションをお持ちでない場合は、開始する前に 無料アカウント を作成してください。
Azure portal での IoT Hub Device Provisioning Service の設定に関するページの手順を完了します。
デバイスをシミュレートするために使用される Windows 開発環境の前提条件は次のとおりです。 Linux または macOS については、SDK ドキュメントの「開発環境を準備する」の該当するセクションを参照してください。
'C++ によるデスクトップ開発' ワークロードを有効にした Visual Studio 2022 をインストールします。 Visual Studio 2015、Visual Studio 2017、および Visual Studio 19 もサポートされています。
最新の CMake ビルド システムをインストールします。 CMake 実行可能ファイルをパスに追加するオプションを必ずオンにします。
重要
CMake
のインストールを開始する前に、Visual Studio の前提条件 (Visual Studio と "C++ によるデスクトップ開発" ワークロード) がコンピューターにインストールされていることを確認する。 前提条件を満たし、ダウンロードを検証したら、CMake ビルド システムをインストールします。 また、旧バージョンの CMake ビルド システムでは、このチュートリアルで使用されるソリューション ファイルを生成できないことに注意してください。 必ず最新バージョンの CMake を使用してください。
Windows 開発環境の前提条件は次のとおりです。 Linux または macOS については、SDK ドキュメントの「開発環境を準備する」の該当するセクションを参照してください。
Windows ベースのコンピューターに .NET SDK 6.0 以降をインストールします。 次のコマンドを使用してバージョンを確認してください。
dotnet --info
Windows 開発環境の前提条件は次のとおりです。 Linux または macOS については、SDK ドキュメントの「開発環境を準備する」の該当するセクションを参照してください。
- マシンに Node.js v4.0 以上をインストールします。
Windows 開発環境の前提条件は次のとおりです。
- コンピューター上の Python 3.6 以降。
Windows 開発環境の前提条件は次のとおりです。 Linux または macOS については、SDK ドキュメントの「開発環境を準備する」の該当するセクションを参照してください。
コンピューターに Java SE Development Kit 8 以降をインストールします。
Maven をダウンロードし、インストールします。
最新バージョンの Git をインストールします。 コマンド ウィンドウからアクセスできる環境変数に Git が追加されていることを確認します。
OpenSSL がコンピューターにインストールされていることを確認する。 Windowsでは、Git のインストールに OpenSSL のインストールが含まれています。 OpenSSL には、Git Bash プロンプトからアクセスできます。 OpenSSL がインストールされていることを確認するには、Git Bash プロンプトを開いて、
openssl version
と入力します。注意
OpenSSL に精通していて、既に Windows コンピューターにインストールしている場合を除き、Git Bash プロンプトから OpenSSL を使用することをお勧めします。 または、ソース コードをダウンロードして OpenSSL をビルドすることもできます。 OpenSSL をビルドまたはダウンロードする場合は、パスで OpenSSL バイナリにアクセスできること、および
OPENSSL_CNF
環境変数が openssl.cnf ファイルのパスに設定されていることを確認してください。
開発環境を準備する
このセクションでは、Azure IoT C SDK のビルドに使用する開発環境を準備します。 SDK には、Data Protection Manager によるデバイスのプロビジョニングに使用するサンプル コードとツールが含まれています。
Web ブラウザーで、Azure IoT C SDK のリリース ページに移動します。
最新リリースの Azure IoT C SDK のタグ名をコピーします (例:
lts_03_2024
)。Windows コマンド プロンプトを開いて、次のコマンドを実行して、最新リリースの C 用 Azure IoT Device SDK の GitHub リポジトリを複製します。
<release-tag>
を前のステップでコピーしたタグで置き換えます。git clone -b <release-tag> https://github.com/Azure/azure-iot-sdk-c.git cd azure-iot-sdk-c git submodule update --init
この操作が完了するまで数分かかる場合があります。
操作が完了したら、
azure-iot-sdk-c
ディレクトリから次のコマンドを実行します。mkdir cmake cd cmake
このコード サンプルでは、X.509 証明書を使用し、X.509 認証によって構成証明を提示します。 次のコマンドを実行して、デバイス プロビジョニング クライアントを含む開発プラットフォームに固有の SDK のバージョンをビルドします。 シミュレートされたデバイスの Visual Studio ソリューションが
cmake
ディレクトリに生成されます。<path
を複製した C SDK に対する絶対パスに置き換えます。cmake -Duse_prov_client:BOOL=ON -Dhsm_custom_lib=c:/<path>/azure-iot-sdk-c/cmake/provisioning_client/samples/custom_hsm_example/Debug/custom_hsm_example.lib ..
ヒント
cmake
で C++ コンパイラが見つからない場合は、上記のコマンドの実行中にビルド エラーが発生する可能性があります。 これが発生した場合は、Visual Studio コマンド プロンプトでコマンドを実行してください。ビルドが成功すると、最後のいくつかの出力行は次の出力のようになります。
cmake -Duse_prov_client:BOOL=ON -Dhsm_custom_lib=c:/azure-iot-sdk-c/cmake/provisioning_client/samples/custom_hsm_example/Debug/custom_hsm_example.lib .. -- Building for: Visual Studio 17 2022 -- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.22000. -- The C compiler identification is MSVC 19.32.31329.0 -- The CXX compiler identification is MSVC 19.32.31329.0 ... -- Configuring done -- Generating done -- Build files have been written to: C:/azure-iot-sdk-c/cmake
Windows コマンド プロンプトを開いて、次のコマンドを使用して、Azure IoT SDK for C# の GitHub リポジトリを複製します。
git clone https://github.com/Azure/azure-iot-sdk-csharp.git
Windows コマンド プロンプトを開いて、次のコマンドを使用して、Azure IoT SDK for Node.js の GitHub リポジトリを複製します。
git clone https://github.com/Azure/azure-iot-sdk-node.git
Windows コマンド プロンプトを開いて、次のコマンドを使用して、Python 用 Azure IoT Device SDK の GitHub リポジトリを複製します。
git clone -b v2 https://github.com/Azure/azure-iot-sdk-python.git --recursive
Note
このチュートリアルで使用するサンプルは、azure-iot-sdk-python リポジトリの v2 ブランチにあります。 Python SDK の V3 はベータ版で使用できます。
Windows コマンドプロンプトを開いて、次のコマンドを使用して、Java 用 Azure IoT サンプルの GitHub リポジトリを複製します。
git clone https://github.com/Azure/azure-iot-sdk-java.git --recursive
ルート
azure-iot-sdk-java
ディレクトリに移動し、プロジェクトをビルドして必要なパッケージをすべてダウンロードします。cd azure-iot-sdk-java mvn install -DskipTests=true
X.509 証明書チェーンを作成する
このセクションでは、このチュートリアルでの各デバイスのテストのために 3 つの証明書から成る X.509 証明書チェーンを生成します。 証明書の階層は次のとおりです。
ルート証明書 DPS を使用したルート証明書をアップロードして検証します。 この検証により、DPS がその証明書を信頼し、その証明書によって署名された証明書を検証できるようになります。
中間証明書: 中間証明書は、製品ラインや会社の部門などを基準としてデバイスを論理的にグループ化する用途に使用するのが一般的です。 このチュートリアルでは、1 つの中間証明書を含む証明書チェーンを使用しますが、運用環境のシナリオでは複数の証明書を使用できます。 このチェーン内の中間証明書は、ルート証明書によって署名されます。 この証明書は、DPS で作成した登録グループに提供されます。 この構成を使うと、同じ中間証明書によって署名されているデバイス証明書があるデバイスのグループ全体をまとめて管理できます。
デバイス証明書: デバイス証明書 (リーフ証明書と呼ばれることもあります) は、中間証明書によって署名され、秘密キーと一緒にデバイスに保存されます。 これらの機密項目は、HSM を使用して安全に保存されるのが理想的です。 複数のデバイス証明書は、同じ中間証明書によって署名できます。 プロビジョニングの試行時には、各デバイスによって、この証明書と秘密キーが証明書チェーンと共に提示されます。
証明書チェーンの詳細については、「X.509 証明書の構成証明」を参照してください。
X.509 OpenSSL 環境を設定する
このセクションでは、Openssl コマンドで使用される Openssl 構成ファイル、ディレクトリ構造、およびその他のファイルを作成します。
Git Bash コマンド プロンプトを開き、このチュートリアルの X.509 証明書とキーを生成するフォルダーに移動します。
ルート CA 証明書の openssl_root_ca.cnf という名前の OpenSSL 構成ファイルを作成します。 OpenSSL 構成ファイルには、OpenSSL コマンドで使用されるポリシーと定義が含まれています。 次のテキストをコピーして、openssl_root_ca.cnf ファイルに貼り付けます。
# OpenSSL root CA configuration file. [ ca ] default_ca = CA_default [ CA_default ] # Directory and file locations. dir = . certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial RANDFILE = $dir/private/.rand # The root key and root certificate. private_key = $dir/private/azure-iot-test-only.root.ca.key.pem certificate = $dir/certs/azure-iot-test-only.root.ca.cert.pem # For certificate revocation lists. crlnumber = $dir/crlnumber crl = $dir/crl/azure-iot-test-only.intermediate.crl.pem crl_extensions = crl_ext default_crl_days = 30 # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 name_opt = ca_default cert_opt = ca_default default_days = 375 preserve = no policy = policy_loose [ policy_strict ] # The root CA should only sign intermediate certificates that match. countryName = optional stateOrProvinceName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ policy_loose ] # Allow the intermediate CA to sign a more diverse range of certificates. countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 # Extension to add when the -x509 option is used. x509_extensions = v3_ca [ req_distinguished_name ] # See <https://en.wikipedia.org/wiki/Certificate_signing_request>. countryName = Country Name (2 letter code) stateOrProvinceName = State or Province Name localityName = Locality Name 0.organizationName = Organization Name organizationalUnitName = Organizational Unit Name commonName = Common Name emailAddress = Email Address # Optionally, specify some defaults. countryName_default = US stateOrProvinceName_default = WA localityName_default = 0.organizationName_default = My Organization organizationalUnitName_default = emailAddress_default = [ v3_ca ] # Extensions for a typical CA. subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ v3_intermediate_ca ] # Extensions for a typical intermediate CA. subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_cert ] # Extensions for client certificates. basicConstraints = CA:FALSE nsComment = "OpenSSL Generated Client Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [ server_cert ] # Extensions for server certificates. basicConstraints = CA:FALSE nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # Extension for CRLs. authorityKeyIdentifier=keyid:always [ ocsp ] # Extension for OCSP signing certificates. basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
中間証明書とデバイス証明書に使用する openssl_device_intermediate_ca.cnf という名前の OpenSSL 構成ファイルを作成します。 次のテキストをコピーして、openssl_device_intermediate_ca.cnf ファイルに貼り付けます。
# OpenSSL root CA configuration file. [ ca ] default_ca = CA_default [ CA_default ] # Directory and file locations. dir = . certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial RANDFILE = $dir/private/.rand # The root key and root certificate. private_key = $dir/private/azure-iot-test-only.intermediate.key.pem certificate = $dir/certs/azure-iot-test-only.intermediate.cert.pem # For certificate revocation lists. crlnumber = $dir/crlnumber crl = $dir/crl/azure-iot-test-only.intermediate.crl.pem crl_extensions = crl_ext default_crl_days = 30 # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 name_opt = ca_default cert_opt = ca_default default_days = 375 preserve = no policy = policy_loose [ policy_strict ] # The root CA should only sign intermediate certificates that match. countryName = optional stateOrProvinceName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ policy_loose ] # Allow the intermediate CA to sign a more diverse range of certificates. countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 # Extension to add when the -x509 option is used. x509_extensions = v3_ca [ req_distinguished_name ] # See <https://en.wikipedia.org/wiki/Certificate_signing_request>. countryName = Country Name (2 letter code) stateOrProvinceName = State or Province Name localityName = Locality Name 0.organizationName = Organization Name organizationalUnitName = Organizational Unit Name commonName = Common Name emailAddress = Email Address # Optionally, specify some defaults. countryName_default = US stateOrProvinceName_default = WA localityName_default = 0.organizationName_default = My Organization organizationalUnitName_default = emailAddress_default = [ v3_ca ] # Extensions for a typical CA. subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ v3_intermediate_ca ] # Extensions for a typical intermediate CA. subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_cert ] # Extensions for client certificates. basicConstraints = CA:FALSE nsComment = "OpenSSL Generated Client Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [ server_cert ] # Extensions for server certificates. basicConstraints = CA:FALSE nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # Extension for CRLs. authorityKeyIdentifier=keyid:always [ ocsp ] # Extension for OCSP signing certificates. basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
このチュートリアルの OpenSSL コマンドが使用するディレクトリ構造、データベース ファイル (index.txt)、シリアル番号ファイル (シリアル) を作成します。
mkdir certs csr newcerts private touch index.txt openssl rand -hex 16 > serial
ルート CA 証明書を作成する
次のコマンドを実行して、ルート CA 秘密キーとルート CA 証明書を作成します。 この証明書とキーを使用して、中間証明書に署名します。
Git Bash ターミナルで、ルート CA 秘密キーを作成します:
openssl genrsa -aes256 -passout pass:1234 -out ./private/azure-iot-test-only.root.ca.key.pem 4096
ルート CA 証明書を作成します:
openssl req -new -x509 -config ./openssl_root_ca.cnf -passin pass:1234 -key ./private/azure-iot-test-only.root.ca.key.pem -subj '//CN=Azure IoT Hub CA Cert Test Only' -days 30 -sha256 -extensions v3_ca -out ./certs/azure-iot-test-only.root.ca.cert.pem
重要
サブジェクト名 (
//CN=Azure IoT Hub CA Cert Test Only
) に追加されているスラッシュは、Windows プラットフォーム上の Git で文字列をエスケープする場合にのみ必要となります。 Linux プラットフォームでは、サブジェクト名にスラッシュ (/CN=Azure IoT Hub CA Cert Test Only
) を 1 つだけ付けます。ルート CA 証明書を調べます。
openssl x509 -noout -text -in ./certs/azure-iot-test-only.root.ca.cert.pem
発行者とサブジェクトの両方がルート CA であることを確認します。
Certificate: Data: Version: 3 (0x2) Serial Number: 1d:93:13:0e:54:07:95:1d:8c:57:4f:12:14:b9:5e:5f:15:c3:a9:d4 Signature Algorithm: sha256WithRSAEncryption Issuer: CN = Azure IoT Hub CA Cert Test Only Validity Not Before: Jun 20 22:52:23 2022 GMT Not After : Jul 20 22:52:23 2022 GMT Subject: CN = Azure IoT Hub CA Cert Test Only Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit)
中間 CA 証明書を作成する
次のコマンドを実行して、中間 CA 秘密キーと中間 CA 証明書を作成します。 この証明書とキーを使用して、デバイス証明書に署名します。
Git Bash ターミナルで、中間 CA 秘密キーを作成します:
openssl genrsa -aes256 -passout pass:1234 -out ./private/azure-iot-test-only.intermediate.key.pem 4096
中間 CA 証明書署名要求 (CSR) を作成します。
openssl req -new -sha256 -passin pass:1234 -config ./openssl_device_intermediate_ca.cnf -subj '//CN=Azure IoT Hub Intermediate Cert Test Only' -key ./private/azure-iot-test-only.intermediate.key.pem -out ./csr/azure-iot-test-only.intermediate.csr.pem
重要
サブジェクト名 (
//CN=Azure IoT Hub Intermediate Cert Test Only
) に追加されているスラッシュは、Windows プラットフォーム上の Git で文字列をエスケープする場合にのみ必要となります。 Linux プラットフォームでは、サブジェクト名に単一のスラッシュ (/CN=Azure IoT Hub Intermediate Cert Test Only
) を付けます。ルート CA 証明書で中間証明書に署名する
openssl ca -batch -config ./openssl_root_ca.cnf -passin pass:1234 -extensions v3_intermediate_ca -days 30 -notext -md sha256 -in ./csr/azure-iot-test-only.intermediate.csr.pem -out ./certs/azure-iot-test-only.intermediate.cert.pem
中間 CA 証明書を確認します。
openssl x509 -noout -text -in ./certs/azure-iot-test-only.intermediate.cert.pem
発行者がルート CA であり、サブジェクトが中間 CA であることを確認します。
Certificate: Data: Version: 3 (0x2) Serial Number: d9:55:87:57:41:c8:4c:47:6c:ee:ba:83:5d:ae:db:39 Signature Algorithm: sha256WithRSAEncryption Issuer: CN = Azure IoT Hub CA Cert Test Only Validity Not Before: Jun 20 22:54:01 2022 GMT Not After : Jul 20 22:54:01 2022 GMT Subject: CN = Azure IoT Hub Intermediate Cert Test Only Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit)
デバイス証明書を作成する
このセクションでは、2 つのデバイス証明書とその完全なチェーン証明書を作成します。 フル チェーン証明書には、デバイス証明書、中間 CA 証明書、ルート CA 証明書が含まれます。 デバイスは、DPS に登録するときに、その完全なチェーン証明書を提示する必要があります。
最初のデバイス秘密キーを作成します。
openssl genrsa -out ./private/device-01.key.pem 4096
新しいデバイス証明書を作成します。
デバイス証明書のサブジェクト共通名 (CN) は、デバイスが DPS への登録に使用する登録 ID に設定する必要があります。 登録 ID は、英数字と特殊文字 (
'-'
、'.'
、'_'
、':'
) から成る、大文字と小文字が区別されない文字列です。 最後の文字は、英数字またはダッシュ ('-'
) である必要があります。 共通名は、この形式に従う必要があります。 DPS では、最大 128 文字の登録 ID がサポートされます。ただし、X.509 証明書のサブジェクト共通名の最大長は 64 文字です。 したがって、X.509 証明書を使用する場合、登録 ID は 64 文字に制限されます。 グループ登録の場合、登録 ID は IoT Hub のデバイス ID としても使用されます。サブジェクトの共通名は、
-subj
パラメーターを使用して設定されます。 次のコマンドでは、共通名が device-01 に設定されています。openssl req -config ./openssl_device_intermediate_ca.cnf -key ./private/device-01.key.pem -subj '//CN=device-01' -new -sha256 -out ./csr/device-01.csr.pem
重要
サブジェクト名 (
//CN=device-01
) に追加されているスラッシュは、Windows プラットフォーム上の Git で文字列をエスケープする場合にのみ必要となります。 Linux プラットフォームでは、サブジェクト名に単一のスラッシュ (/CN=device-01
) を付けます。デバイス証明書に署名します。
openssl ca -batch -config ./openssl_device_intermediate_ca.cnf -passin pass:1234 -extensions usr_cert -days 30 -notext -md sha256 -in ./csr/device-01.csr.pem -out ./certs/device-01.cert.pem
デバイス証明書を確認します。
openssl x509 -noout -text -in ./certs/device-01.cert.pem
発行者が中間 CA であり、サブジェクトがデバイス登録 ID
device-01
であることを確認します。Certificate: Data: Version: 3 (0x2) Serial Number: d9:55:87:57:41:c8:4c:47:6c:ee:ba:83:5d:ae:db:3a Signature Algorithm: sha256WithRSAEncryption Issuer: CN = Azure IoT Hub Intermediate Cert Test Only Validity Not Before: Jun 20 22:55:39 2022 GMT Not After : Jul 20 22:55:39 2022 GMT Subject: CN = device-01 Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit)
デバイスは、DPS で認証するときに、完全な証明書チェーンを提示する必要があります。 証明書チェーンを作成するには、次のコマンドを使用します。
cat ./certs/device-01.cert.pem ./certs/azure-iot-test-only.intermediate.cert.pem ./certs/azure-iot-test-only.root.ca.cert.pem > ./certs/device-01-full-chain.cert.pem
証明書チェーン ファイル ./certs/device-01-full-chain.cert.pem をテキスト エディターで開いて調べます。 証明書チェーンのテキストには、証明書を 3 つすべて使った完全なチェーンが記載されています。 この証明書チェーンは、このチュートリアルで後ほど
device-01
をプロビジョニングするために使います。チェーン テキストの全文は次のような形式になっています。
-----BEGIN CERTIFICATE----- <Text for the device certificate includes public key> -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- <Text for the intermediate certificate includes public key> -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- <Text for the root certificate includes public key> -----END CERTIFICATE-----
2 番目のデバイスの秘密キー、X.509 証明書、および完全なチェーン証明書を作成するには、このスクリプトをコピーして Git Bash コマンド プロンプトに貼り付けます。 他のデバイスの証明書を作成するには、スクリプトの先頭で宣言された
registration_id
変数を変更します。registration_id=device-02 echo $registration_id openssl genrsa -out ./private/${registration_id}.key.pem 4096 openssl req -config ./openssl_device_intermediate_ca.cnf -key ./private/${registration_id}.key.pem -subj "//CN=$registration_id" -new -sha256 -out ./csr/${registration_id}.csr.pem openssl ca -batch -config ./openssl_device_intermediate_ca.cnf -passin pass:1234 -extensions usr_cert -days 30 -notext -md sha256 -in ./csr/${registration_id}.csr.pem -out ./certs/${registration_id}.cert.pem cat ./certs/${registration_id}.cert.pem ./certs/azure-iot-test-only.intermediate.cert.pem ./certs/azure-iot-test-only.root.ca.cert.pem > ./certs/${registration_id}-full-chain.cert.pem
重要
サブジェクト名 (
//CN=$registration_id
) に追加されているスラッシュは、Windows プラットフォーム上の Git で文字列をエスケープする場合にのみ必要となります。 Linux プラットフォームでは、サブジェクト名に単一のスラッシュ (/CN=$registration_id
) を付けます。Note
このスクリプトでは、秘密キーと証明書ファイルの基本ファイル名として登録 ID を使用します。 登録 ID に有効なファイル名文字ではない文字が含まれている場合は、それに応じてスクリプトを変更する必要があります。
警告
証明書のテキストには、公開キーの情報のみが含まれます。
しかし、デバイスはデバイス証明書の秘密キーにもアクセスできる必要があります。 その理由は、プロビジョニングの試行時に、デバイスでそのキーを使って検証を実施する必要があるからです。 このキーの機密性こそ、現実の HSM 内のハードウェアベースのストレージを使用して秘密キーを保護することが推奨される主な理由の 1 つです。
このチュートリアルの残りの部分では、次のファイルを使用します。
証明書 | ファイル | 説明 |
---|---|---|
ルート CA 証明書。 | certs/azure-iot-test-only.root.ca.cert.pem | DPS にアップロードされ、確認されます。 |
中間 CA 証明書 | certs/azure-iot-test-only.intermediate.cert.pem | DPS で登録グループを作成するために使用されます。 |
device-01 秘密キー | private/device-01.key.pem | DPS での認証中にデバイス証明書の所有権を確認するためにデバイスによって使用されます。 |
device-01 フル チェーン証明書 | certs/device-01-full-chain.cert.pem | DPS の認証と登録を行うためにデバイスによって提示されます。 |
device-02 秘密キー | private/device-02.key.pem | DPS での認証中にデバイス証明書の所有権を確認するためにデバイスによって使用されます。 |
device-02 フル チェーン証明書 | certs/device-02-full-chain.cert.pem | DPS の認証と登録を行うためにデバイスによって提示されます。 |
ルート証明書の所有権を検証する
DPS が認証時にデバイスの証明書チェーンを検証できるようにするには、ルート CA 証明書の所有権をアップロードして確認する必要があります。 ルート CA 証明書を DPS インスタンスに追加するには、次の手順に従います。
Azure portal で Device Provisioning Service インスタンスに移動します。
左側のメニューから [証明書] を開き、[追加] を選択して新しい証明書を追加します。
証明書のわかりやすい表示名を入力します。 証明書ファイル
certs/azure-iot-test-only.root.ca.cert.pem
の場所を参照します。 [アップロード] を選択します。[証明書の状態をアップロード時に確認済みに設定する] の横のチェック ボックスを選択します。
[保存] を選択します。
[証明書] タブに、"確認済み" 状態で証明書が表示されることを確認します。
Windows ベースのデバイス上の証明書ストアを更新する
Windows 以外のデバイスでは、証明書チェーンをコードから証明書ストアとして渡すことができます。
Windows ベースのデバイスでは、Windows の証明書ストアに署名証明書 (ルートと中間) を追加する必要があります。 そうしないと、トランスポート層セキュリティ (TLS) を使用した安全なチャネルで署名証明書が DPS に転送されなくなります。
ヒント
C SDK でセキュリティ保護されたチャネル (Schannel) を使用するのではなく、OpenSSL を使用することもできます。 OpenSSL の使用の詳細については、「SDK での OpenSSL の使用」を参照してください。
Windows ベースのデバイスの証明書ストアに署名証明書を追加するには:
Git Bash ターミナルで、以下のように署名証明書を
.pfx
に変換します。ルート CA 証明書:
openssl pkcs12 -inkey ./private/azure-iot-test-only.root.ca.key.pem -in ./certs/azure-iot-test-only.root.ca.cert.pem -export -passin pass:1234 -passout pass:1234 -out ./certs/root.pfx
中間 CA 証明書:
openssl pkcs12 -inkey ./private/azure-iot-test-only.intermediate.key.pem -in ./certs/azure-iot-test-only.intermediate.cert.pem -export -passin pass:1234 -passout pass:1234 -out ./certs/intermediate.pfx
Windows の [スタート] ボタンを右クリックし、[実行] を選択します。 「certmgr.msc」と入力し、[OK] を選択して、証明書マネージャーを起動します。
証明書マネージャーの [証明書 - 現在のユーザー] で、[信頼されたルート証明機関] を選択します。 次に、メニューで [アクション]>[すべてのタスク]>[インポート] の順に選択します。
証明書のインポート ウィザードの手順に従って、
root.pfx
をインポートします。- Personal Information Exchange (.pfx) で検索してください。
- パスワードには
1234
を使用します。 - 証明書は、 [信頼されたルート証明機関] 証明書ストアに配置します。
上記の証明書マネージャーの手順を繰り返して、
intermediate.pfx
をインポートします。- 証明書は、 [中間証明機関] 証明書ストアに配置します。
これで、Windows ベースのデバイスで署名証明書が信頼され、チェーン全体を DPS に転送できるようになりました。
登録グループを作成する
Azure portal にサインインし、Device Provisioning Service インスタンスに移動します。
ナビゲーション メニューの [設定] セクションから [Manage enrollments] (登録の管理) を選択します。
ページの上部で、[登録グループの追加] を選択します。
[登録グループの追加] ページの [Registration + provisioning] (登録とプロビジョニング) タブで、次の情報を入力して登録グループの詳細を構成します。
フィールド 説明 構成証明 この登録グループのみに使用する中間証明書をアップロードする場合は、[Attestation mechanism] (構成証明メカニズム) として [X.509 intermediate certificates] (X.509 中間証明書) を選択し、中間証明書を既にアップロードしている場合は [X.509 certificates uploaded to this Device Provisioning Service] (この Device Provisioning Service にアップロードされた X.509 証明書) を選択します。 X.509 certificate settings (X.509 証明書の設定) 選択した構成証明方法に応じて、この登録グループのプライマリとセカンダリの中間証明書をアップロードまたは選択します。 グループ名 デバイスのグループの名前を指定します。 登録グループ名は、英数字と特殊文字 ( '-'
、'.'
、'_'
、':'
) から成る、大文字と小文字が区別されない文字列です (最大 128 文字)。 最後の文字は、英数字またはダッシュ ('-'
) である必要があります。プロビジョニングの状態 この登録グループをデバイスのプロビジョニングに使用できるようにする場合は、[Enable this enrollment] (この登録を有効にする) ボックスをオンにします。 グループを無効にする場合は、このボックスをオフにします。 この設定は後で変更できます。 再プロビジョニング ポリシー 再プロビジョニングを要求するデバイスを DPS で処理する方法を反映する再プロビジョニング ポリシーを選択します。 詳細については、「再プロビジョニング ポリシー」を参照してください [Next: IoT hubs] (次へ: IoT ハブ) を選択します。
[登録グループの追加] ページの [IoT ハブ] タブで、次の情報を入力して、登録グループでデバイスをプロビジョニングできる IoT ハブを決定します。
フィールド 説明 Target IoT hubs (ターゲット IoT ハブ) 1 つ以上のリンクされた IoT ハブを選択するか、IoT ハブへの新しいリンクを追加します。 IoT ハブを DPS インスタンスにリンクする方法の詳細については、IoT ハブをリンクして管理する方法に関するページを参照してください。 割り当てポリシー 複数のリンクされた IoT ハブを選択した場合は、デバイスを別のハブに割り当てる方法を選択します。 割り当てポリシーの詳細については、割り当てポリシーの使用方法に関するページを参照してください。
リンクされた IoT ハブを 1 つだけ選択した場合は、[加重が均等に分布] ポリシーを使用することをお勧めします。[Next: Device settings] (次へ: デバイスの設定) を選択します
[登録グループの追加] ページの [Device settings] (デバイスの設定) タブで、次の情報を入力して、新しくプロビジョニングされたデバイスの構成方法を定義します。
フィールド 説明 IoT Edge このグループを使用してプロビジョニングされたすべてのデバイスで Azure IoT Edge が実行される場合は、[プロビジョニングされたデバイスで IoT Edge を有効にする] をオンにします。 このグループが IoT Edge 非対応デバイス用だけの場合は、このボックスをオフにします。 グループ内のすべてのデバイスが IoT Edge 対応か、すべてが非対応かのどちらかになります。 デバイス タグ このテキスト ボックスを使用して、プロビジョニングされたデバイスのデバイス ツインに適用するタグを指定します。 Desired properties (必要なプロパティ) このテキスト ボックスを使用して、プロビジョニングされたデバイスのデバイス ツインに適用する必要なプロパティを指定します。 詳細については、「IoT Hub のデバイス ツインの理解と使用」を参照してください。
確認と作成 をクリックします。
[確認 + 作成] タブで、すべての値を確認してから [作成] を選択します。
デバイス プロビジョニング コードを準備して実行する
このセクションでは、Device Provisioning Service インスタンス情報を使用してサンプル コードを更新します。 デバイスは認証されると、このセクションで構成された Device Provisioning Service インスタンスにリンクされている IoT ハブに割り当てられます。
このセクションでは、Git Bash プロンプトと Visual Studio IDE を使用します。
デバイスのプロビジョニング コードを構成する
このセクションでは、Device Provisioning Service インスタンス情報を使用してサンプル コードを更新します。
Azure portal で、デバイス プロビジョニングサービス インスタンスの [概要] タブを選択し、[ID スコープ] の値をメモします。
Visual Studio を起動し、Git リポジトリ azure-iot-sdk-c のルートに作成した
cmake
ディレクトリに作成された新しいソリューション ファイルを開きます。 ソリューション ファイルの名前はazure_iot_sdks.sln
です。Visual Studio のソリューション エクスプローラーで [Provision_Samples] > [prov_dev_client_sample] > [ソース ファイル]の順に移動し、prov_dev_client_sample.c を開きます。
定数
id_scope
を探し、以前にコピーした ID スコープの値で置き換えます。 たとえば次のような点です。static const char* id_scope = "0ne00000A0A";
同じファイル内で
main()
関数の定義を探します。hsm_type
変数がSECURE_DEVICE_TYPE_X509
に設定されていること、および他のすべてのhsm_type
行がコメントアウトされていることを確認します。例:SECURE_DEVICE_TYPE hsm_type; //hsm_type = SECURE_DEVICE_TYPE_TPM; hsm_type = SECURE_DEVICE_TYPE_X509; //hsm_type = SECURE_DEVICE_TYPE_SYMMETRIC_KEY;
変更を保存します。
prov_dev_client_sample プロジェクトを右クリックし、[スタートアップ プロジェクトに設定] を選択します。
カスタム HSM スタブ コードを構成する
実際のハードウェアベースのストレージとやり取りする際の詳細は、デバイスのハードウェアに応じて異なります。 このチュートリアルのシミュレートされたデバイスで使用される証明書チェーンを、カスタム HSM スタブ コードにハードコードします。 実際には、機密情報のセキュリティを強化するために、実際の HSM ハードウェアに証明書チェーンが格納されます。 そのうえで、このサンプルで使用されたスタブ メソッドとよく似たメソッドを実装し、ハードウェアベースのストレージからシークレットを読み取れるようにします。
HSM ハードウェアは必須ではありませんが、証明書の秘密キーなど、機密情報を保護するために推奨されます。 実際の HSM がサンプルによって呼び出されると、秘密キーはソース コードに現れません。 キーをソース コードに含めると、コードを表示できるすべてのユーザーに対してキーが公開されます。 これは、学習を支援するために、このチュートリアルでのみ行います。
ID device-01
でデバイスの ID をシミュレートするようにカスタム HSM スタブ コードを更新するには:
Visual Studio のソリューション エクスプローラーで [Provision_Samples] > [custom_hsm_example] > [ソース ファイル] の順に移動し、custom_hsm_example.c を開きます。
COMMON_NAME
文字列定数の文字列値を、デバイス証明書の生成時に使用した共通名に更新します。static const char* const COMMON_NAME = "device-01";
Git Bash ターミナルで次のコマンドを実行し、デバイス証明書の文字列定数を生成します:
sed -e 's/^/"/;$ !s/$/""\\n"/;$ s/$/"/' ./certs/device-01-full-chain.cert.pem
このコマンドの出力をコピーします。
証明書が生成された後に ./certs/device-01-full-chain.cert.pem に保存した証明書チェーンを使用して
CERTIFICATE
定数文字列の文字列値を更新します。 定数値には、前の手順で出力した証明書テキストを使用します。証明書のテキストの構文は、次のパターンに一致する必要があります。Visual Studio によって余分なスペースが追加されたり、解析が実行されたりしないようにしてください。
// <Device/leaf cert> // <intermediates> // <root> static const char* const CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" "MIIFOjCCAyKgAwIBAgIJAPzMa6s7mj7+MA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV\n" ... "MDMwWhcNMjAxMTIyMjEzMDMwWjAqMSgwJgYDVQQDDB9BenVyZSBJb1QgSHViIENB\n" "-----END CERTIFICATE-----\n" "-----BEGIN CERTIFICATE-----\n" "MIIFPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQsFADAqMSgwJgYDVQQDDB9BenVy\n" ... "MTEyMjIxMzAzM1owNDEyMDAGA1UEAwwpQXp1cmUgSW9UIEh1YiBJbnRlcm1lZGlh\n" "-----END CERTIFICATE-----\n" "-----BEGIN CERTIFICATE-----\n" "MIIFOjCCAyKgAwIBAgIJAPzMa6s7mj7+MA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV\n" ... "MDMwWhcNMjAxMTIyMjEzMDMwWjAqMSgwJgYDVQQDDB9BenVyZSBJb1QgSHViIENB\n" "-----END CERTIFICATE-----";
Git Bash で、次のコマンドを実行し、デバイス秘密キーの文字列定数を生成します:
sed -e 's/^/"/;$ !s/$/""\\n"/;$ s/$/"/' ./private/device-01.key.pem
このコマンドの出力をコピーします。
PRIVATE_KEY
定数の文字列値を、デバイス証明書の秘密キーで更新します。 定数値には、前の手順で出力した秘密キー テキストを使用します。秘密キーのテキストの構文は、次のパターンに一致する必要があります。Visual Studio によって余分なスペースが追加されたり、解析が実行されたりしないようにしてください。
static const char* const PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\n" "MIIJJwIBAAKCAgEAtjvKQjIhp0EE1PoADL1rfF/W6v4vlAzOSifKSQsaPeebqg8U\n" ... "X7fi9OZ26QpnkS5QjjPTYI/wwn0J9YAwNfKSlNeXTJDfJ+KpjXBcvaLxeBQbQhij\n" "-----END RSA PRIVATE KEY-----";
変更を保存します。
custom_hsm_example プロジェクトを右クリックして [ビルド] を選択します。
重要
次のセクションでソリューションの残りの部分をビルドする前に、custom_hsm_example プロジェクトをビルドする必要があります。
サンプルを実行する
Visual Studio のメニューで [デバッグ]>[デバッグなしで開始] の順に選択して、ソリューションを実行します。 プロジェクトをリビルドするよう求められたら、 [はい] を選択して、プロジェクトをリビルドしてから実行します。
次の出力は、シミュレートされたデバイス
device-01
が正常に起動し、プロビジョニング サービスに接続した場合の例です。 デバイスは IoT ハブに割り当てられ、登録されています。Provisioning API Version: 1.8.0 Registering Device Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Registration Information received from service: contoso-hub-2.azure-devices.net, deviceId: device-01 Press enter key to exit:
「2 番目のデバイス (
device-02
) のカスタム HSM スタブ コードを構成する」の手順を繰り返し、もう一度サンプルを実行します。 このデバイスには次の値を使用します。説明 値 共通名 "device-02"
完全な証明書チェーン ./certs/device-02-full-chain.cert.pem を使用してテキストを生成する 秘密キー ./private/device-02.key.pem を使用してテキストを生成する 次の出力は、シミュレートされたデバイス
device-02
が正常に起動し、プロビジョニング サービスに接続した場合の例です。 デバイスは IoT ハブに割り当てられ、登録されています。Provisioning API Version: 1.8.0 Registering Device Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Registration Information received from service: contoso-hub-2.azure-devices.net, deviceId: device-02 Press enter key to exit:
C# サンプル コードは、パスワードで保護された PKCS#12 形式のファイル (.ptx) に格納された X.509 証明書を使うように設定されています。 以前作成した完全なチェーン証明書は PEM 形式です。 完全なチェーン証明書を PKCS#12 形式に変換するには、前回 OpenSSL コマンドを実行したディレクトリから Git Bash プロンプトに次のコマンドを入力します。
device-01
openssl pkcs12 -inkey ./private/device-01.key.pem -in ./certs/device-01-full-chain.cert.pem -export -passin pass:1234 -passout pass:1234 -out ./certs/device-01-full-chain.cert.pfx
device-02
openssl pkcs12 -inkey ./private/device-02.key.pem -in ./certs/device-02-full-chain.cert.pem -export -passin pass:1234 -passout pass:1234 -out ./certs/device-02-full-chain.cert.pfx
このセクションのこれ以降の部分では、Windows コマンド プロンプトを使います。
Azure portal で、Device Provisioning Service の [概要] タブを選択します。
[ID スコープ] の値をコピーします。
Windowsコマンド プロンプトで、X509Sample ディレクトリに変更します。 このディレクトリは、前の手順で複製した SDK リポジトリにあります: .\azure-iot-sdk-csharp\provisioning\device\samples\getting started\X509Sample。
次のコマンドを入力して、X.509 デバイス プロビジョニング サンプルをビルドして実行します。
<id-scope>
を、Azure portal からコピーした ID スコープに置き換えます。<your-certificate-folder>
を、OpenSSL コマンドを実行したフォルダーへのパスに置き換えます。dotnet run -- -s <id-scope> -c <your-certificate-folder>\certs\device-01-full-chain.cert.pfx -p 1234
そのデバイスは DPS に接続され、IoT ハブに割り当てられます。 その後、デバイスは IoT ハブにテレメトリ メッセージを送信します。 次の例のような出力が表示されます。
Loading the certificate... Found certificate: 3E5AA3C234B2032251F0135E810D75D38D2AA477 CN=Azure IoT Hub CA Cert Test Only; PrivateKey: False Found certificate: 81FE182C08D18941CDEEB33F53F8553BA2081E60 CN=Azure IoT Hub Intermediate Cert Test Only; PrivateKey: False Found certificate: 5BA1DB226D50EBB7A6A6071CED4143892855AE43 CN=device-01; PrivateKey: True Using certificate 5BA1DB226D50EBB7A6A6071CED4143892855AE43 CN=device-01 Initializing the device provisioning client... Initialized for registration Id device-01. Registering with the device provisioning service... Registration status: Assigned. Device device-01 registered to contoso-hub-2.azure-devices.net. Creating X509 authentication for IoT Hub... Testing the provisioned device with IoT Hub... Sending a telemetry message... Finished.
Note
コマンド ラインで証明書とパスワードを指定しない場合、証明書ファイルは既定で ./certificate.pfx となり、パスワードの入力を求められます。
追加のパラメーターを渡して TransportType (-t) と GlobalDeviceEndpoint (-g) を変更できます。 全種類のパラメーターの一覧を表示するには、
dotnet run -- --help
を実行します。2 つ目のデバイスを登録するには、その完全なチェーン証明書を使ってサンプルを再実行します。
dotnet run -- -s <id-scope> -c <your-certificate-folder>\certs\device-02-full-chain.cert.pfx -p 1234
次の手順では、Windows コマンド プロンプトを使います。
Azure portal で、Device Provisioning Service の [概要] タブを選択します。
[ID スコープ] の値をコピーします。
Windowsコマンド プロンプトで、サンプル ディレクトリに移動して、サンプルに必要なパッケージをインストールします。 表示されるパスは、SDK を複製した場所に相対しています。
cd .\azure-iot-sdk-node\provisioning\device\samples npm install
provisioning/device/samples フォルダーの register_x509.js を開いて、コードを確認します。
サンプルでは、トランスポート プロトコルとして MQTT が規定値となっています。 別のプロトコルを使用したい場合は、以下の行をコメントアウトし、適切なプロトコルの行をコメント解除してください。
var ProvisioningTransport = require('azure-iot-provisioning-device-mqtt').Mqtt;
DPS を使って IoT デバイスの認証とプロビジョニングを行うために、このサンプルでは 5 つの環境変数を使用しています。 それらの環境変数を次に示します。
変数名 説明 PROVISIONING_HOST
DPS インスタンスに接続するために使うエンドポイント。 このチュートリアルでは、グローバル エンドポイント global.azure-devices-provisioning.net
を使います。PROVISIONING_IDSCOPE
DPS インスタンスのための ID スコープ。 PROVISIONING_REGISTRATION_ID
デバイスの登録 ID。 デバイス証明書のサブジェクト共通名と一致する必要があります。 CERTIFICATE_FILE
デバイスの完全チェーン証明書ファイルへのパス。 KEY_FILE
デバイス証明書の秘密キー ファイルへのパス。 ProvisioningDeviceClient.register()
メソッドはデバイスの登録を試みます。グローバル デバイス エンドポイントと ID スコープのための環境変数を追加します。
<id-scope>
を、Azure portal からコピーした値に置き換えます。set PROVISIONING_HOST=global.azure-devices-provisioning.net set PROVISIONING_IDSCOPE=<id-scope>
デバイス登録 ID のための環境変数を設定します。 IoT デバイスの登録 ID は、そのデバイス証明書上のサブジェクト共通名と一致している必要があります。 このチュートリアルでは、デバイスのサブジェクト名と登録 ID の両方を device-01 とします。
set PROVISIONING_REGISTRATION_ID=device-01
デバイス の完全チェーン証明書ファイルと生成済みのデバイス秘密キー ファイルのための環境変数を設定します。
<your-certificate-folder>
を、OpenSSL コマンドを実行したフォルダーへのパスに置き換えます。set CERTIFICATE_FILE=<your-certificate-folder>\certs\device-01-full-chain.cert.pem set KEY_FILE=<your-certificate-folder>\private\device-01.key.pem
サンプルを実行して、デバイスが正常にプロビジョニングされたことを検証します。
node register_x509.js
次の例のような出力が表示されます。
registration succeeded assigned hub=contoso-hub-2.azure-devices.net deviceId=device-01 Client connected send status: MessageEnqueued
次の表に従って 2 番目のデバイス (
device-02
) の環境変数を更新し、サンプルをもう一度実行します。環境変数 値 PROVISIONING_REGISTRATION_ID device-02
CERTIFICATE_FILE <[証明書のフォルダー]>\certs\device-02-full-chain.cert.pem KEY_FILE <[証明書のフォルダー]>\private\device-02.key.pem
次の手順では、Windows コマンド プロンプトを使います。
Azure portal で、Device Provisioning Service の [概要] タブを選択します。
ID スコープ の値をコピーします。
Windowsコマンド プロンプトで、provision_x509.py サンプルのディレクトリに移動します。 表示されるパスは、SDK を複製した場所に相対しています。
cd .\azure-iot-sdk-python\samples\async-hub-scenarios
DPS を使用して IoT デバイスの認証とプロビジョニングを行うために、このサンプルでは 6 つの環境変数を使用しています。 それらの環境変数を次に示します。
変数名 説明 PROVISIONING_HOST
DPS インスタンスに接続するために使うエンドポイント。 このチュートリアルでは、グローバル エンドポイント global.azure-devices-provisioning.net
を使います。PROVISIONING_IDSCOPE
DPS インスタンスのための ID スコープ。 DPS_X509_REGISTRATION_ID
デバイスの登録 ID。 デバイス証明書のサブジェクト共通名と一致する必要があります。 X509_CERT_FILE
デバイスの完全チェーン証明書ファイルへのパス。 X509_KEY_FILE
デバイス証明書の秘密キー ファイルへのパス。 PASS_PHRASE
秘密キー ファイルを暗号化するために使われるパス フレーズ (使う場合)。 このチュートリアルでは必要ありません。 グローバル デバイス エンドポイントと ID スコープの環境変数を追加します。 ID スコープ変数の場合は、Azure portal からコピーした値を使用します。
set PROVISIONING_HOST=global.azure-devices-provisioning.net set PROVISIONING_IDSCOPE=<ID scope for your DPS resource>
デバイス登録 ID のための環境変数を設定します。 IoT デバイスの登録 ID は、そのデバイス証明書上のサブジェクト共通名と一致している必要があります。 このチュートリアルでは、デバイスのサブジェクト名と登録 ID の両方を device-01 とします。
set DPS_X509_REGISTRATION_ID=device-01
デバイス の完全チェーン証明書ファイルと生成済みのデバイス秘密キー ファイルのための環境変数を設定します。
<your-certificate-folder>
を、OpenSSL コマンドを実行したフォルダーへのパスに置き換えます。set X509_CERT_FILE=<your-certificate-folder>\certs\device-01-full-chain.cert.pem set X509_KEY_FILE=<your-certificate-folder>\private\device-01.key.pem
provision_x509.py のコードを確認します。 Python バージョン 3.7 以降を使用しない場合は、こちらに記載されているコード変更を行って
asyncio.run(main())
を置き換えてください。サンプルを実行します。 サンプルは、IoT ハブにデバイスをプロビジョニングする DPS に接続します。 デバイスがプロビジョニングされると、サンプルはいくつかのテスト メッセージを IoT ハブに送信します。
python provision_x509.py
次の例のような出力が表示されます。
The complete registration result is device-01 contoso-hub-2.azure-devices.net initialAssignment null Will send telemetry from the provisioned device sending message #1 sending message #2 sending message #3 sending message #4 sending message #5 sending message #6 sending message #7 sending message #8 sending message #9 sending message #10 done sending message #1 done sending message #2 done sending message #3 done sending message #4 done sending message #5 done sending message #6 done sending message #7 done sending message #8 done sending message #9 done sending message #10
次の表に従って 2 番目のデバイス (
device-02
) の環境変数を更新し、サンプルをもう一度実行します。環境変数 値 DPS_X509_REGISTRATION_ID device-02
X509_CERT_FILE <[証明書のフォルダー]>\certs\device-02-full-chain.cert.pem X509_KEY_FILE <[証明書のフォルダー]>\private\device-02.key.pem
次のセクションでは、Windows コマンド プロンプトと Git Bash プロンプトの両方を使います。
Azure portal で、Device Provisioning Service の [概要] タブを選択します。
ID スコープ の値をコピーします。
Windows コマンド プロンプトで、サンプル プロジェクト フォルダーに移動します。 表示されるパスは、SDK を複製した場所に相対しています。
cd .\azure-iot-sdk-java\provisioning\provisioning-device-client-samples\provisioning-X509-sample
プロビジョニング サービスと X.509 の ID 情報をサンプル コードに入力します。 これはプロビジョニング中、デバイス登録の前に、シミュレートされたデバイスの構成証明に使用されます。
使い慣れたエディターでファイル
.\src\main\java\samples\com\microsoft\azure\sdk\iot\ProvisioningX509Sample.java
を開きます次の値を更新します。
idScope
には、前にコピーした ID スコープ を使います。 グローバル エンドポイントには、グローバル デバイス エンドポイント を使います。 このエンドポイントは、すべての DPS インスタンスglobal.azure-devices-provisioning.net
で同じです。private static final String idScope = "[Your ID scope here]"; private static final String globalEndpoint = "[Your Provisioning Service Global Endpoint here]";
サンプルでは、トランスポート プロトコルとして HTTPS を使うことが規定値となっています。 別のプロトコルを使いたい場合は、次の行をコメントアウトし、使いたいプロトコルの行をコメント解除してください。
private static final ProvisioningDeviceClientTransportProtocol PROVISIONING_DEVICE_CLIENT_TRANSPORT_PROTOCOL = ProvisioningDeviceClientTransportProtocol.HTTPS;
leafPublicPem
定数文字列の値を、デバイス証明書の値 device-01.cert.pem で更新します。証明書のテキストの構文は、次のパターンに一致する必要があります。余分なスペースや文字が追加されないようにしてください。
private static final String leafPublicPem = "-----BEGIN CERTIFICATE-----\n" "MIIFOjCCAyKgAwIBAgIJAPzMa6s7mj7+MA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV\n" ... "MDMwWhcNMjAxMTIyMjEzMDMwWjAqMSgwJgYDVQQDDB9BenVyZSBJb1QgSHViIENB\n" "-----END CERTIFICATE-----";
この文字列値を手動で更新すると、エラーが発生する可能性があります。 適切な構文を生成するには、次のコマンドをコピーして Git Bash プロンプトに貼り付けて、ENTER キーを押します。 このコマンドは
leafPublicPem
文字列定数値の構文を生成して、出力に書き込みます。sed 's/^/"/;$ !s/$/\\n" +/;$ s/$/"/' ./certs/device-01.cert.pem
定数値の証明書の出力テキストをコピーして貼り付けます。
leafPrivateKey
定数の文字列値を、デバイス証明書の暗号化されていない秘密キー (unencrypted-device-key.pem) で更新します。秘密キーのテキストの構文は、次のパターンに一致する必要があります。余分なスペースや文字が追加されないようにしてください。
private static final String leafPrivateKey = "-----BEGIN PRIVATE KEY-----\n" + "MIIJJwIBAAKCAgEAtjvKQjIhp0EE1PoADL1rfF/W6v4vlAzOSifKSQsaPeebqg8U\n" + ... "X7fi9OZ26QpnkS5QjjPTYI/wwn0J9YAwNfKSlNeXTJDfJ+KpjXBcvaLxeBQbQhij\n" + "-----END PRIVATE KEY-----";
適切な構文を生成するには、次のコマンドをコピーして Git Bash プロンプトに貼り付けて、ENTER キーを押します。 このコマンドは
leafPrivateKey
文字列定数値の構文を生成して、出力に書き込みます。sed 's/^/"/;$ !s/$/\\n" +/;$ s/$/"/' ./private/device-01.key.pem
定数値の秘密キーの出力テキストをコピーして貼り付けます。
ルート CA 証明書の値 azure-iot-test-only.root.ca.cert.pem を含む
rootPublicPem
定数文字列を追加します。 それをleafPrivateKey
定数の直後に追加できます。証明書のテキストの構文は、次のパターンに一致する必要があります。余分なスペースや文字が追加されないようにしてください。
private static final String rootPublicPem = "-----BEGIN CERTIFICATE-----\n" "MIIFOjCCAyKgAwIBAgIJAPzMa6s7mj7+MA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV\n" ... "MDMwWhcNMjAxMTIyMjEzMDMwWjAqMSgwJgYDVQQDDB9BenVyZSBJb1QgSHViIENB\n" "-----END CERTIFICATE-----";
適切な構文を生成するには、次のコマンドをコピーして Git Bash プロンプトに貼り付けて、ENTER キーを押します。 このコマンドは
rootPublicPem
文字列定数値の構文を生成して、出力に書き込みます。sed 's/^/"/;$ !s/$/\\n" +/;$ s/$/"/' ./certs/azure-iot-test-only.root.ca.cert.pem
定数値の証明書の出力テキストをコピーして貼り付けます。
中間 CA 証明書の値 azure-iot-test-only.intermediate.cert.pem を含む
intermediatePublicPem
定数文字列を追加します。 それを以前の定数の直後に追加できます。証明書のテキストの構文は、次のパターンに一致する必要があります。余分なスペースや文字が追加されないようにしてください。
private static final String intermediatePublicPem = "-----BEGIN CERTIFICATE-----\n" "MIIFOjCCAyKgAwIBAgIJAPzMa6s7mj7+MA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV\n" ... "MDMwWhcNMjAxMTIyMjEzMDMwWjAqMSgwJgYDVQQDDB9BenVyZSBJb1QgSHViIENB\n" "-----END CERTIFICATE-----";
適切な構文を生成するには、次のコマンドをコピーして Git Bash プロンプトに貼り付けて、ENTER キーを押します。 このコマンドは
intermediatePublicPem
文字列定数値の構文を生成して、出力に書き込みます。sed 's/^/"/;$ !s/$/\\n" +/;$ s/$/"/' ./certs/azure-iot-test-only.intermediate.cert.pem
定数値の証明書の出力テキストをコピーして貼り付けます。
main
メソッド内で、以下の行を見つけます。// For group enrollment uncomment this line //signerCertificatePemList.add("<Your Signer/intermediate Certificate Here>");
中間 CA 証明書とルート CA 証明書を署名チェーンに追加するには、これらの 2 つの行をその直下に追加します。 署名チェーンには、DPS で検証した証明書までの証明書チェーン全体が含まれる必要があります。
signerCertificatePemList.add(intermediatePublicPem); signerCertificatePemList.add(rootPublicPem);
Note
署名証明書を追加する順序は重要です。 その順序が正しくなければ、サンプルは失敗します。
変更を保存します。
サンプルをビルドしてから、
target
フォルダーへ移動します。mvn clean install cd target
ビルドは .jar ファイルを
target
フォルダーに、ファイル形式provisioning-x509-sample-{version}-with-deps.jar
で出力します (例:provisioning-x509-sample-1.8.1-with-deps.jar
)。 jar ファイルを実行します。 バージョンは次のコマンドで置き換えが必要になる場合があります。java -jar ./provisioning-x509-sample-1.8.1-with-deps.jar
サンプルは、IoT ハブにデバイスをプロビジョニングする DPS に接続します。 デバイスがプロビジョニングされると、サンプルはいくつかのテスト メッセージを IoT ハブに送信します。
Starting... Beginning setup. WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance. 2022-10-21 10:41:20,476 DEBUG (main) [com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClient] - Initialized a ProvisioningDeviceClient instance using SDK version 2.0.2 2022-10-21 10:41:20,479 DEBUG (main) [com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClient] - Starting provisioning thread... Waiting for Provisioning Service to register 2022-10-21 10:41:20,482 INFO (global.azure-devices-provisioning.net-4f8279ac-CxnPendingConnectionId-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Opening the connection to device provisioning service... 2022-10-21 10:41:20,652 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Connection to device provisioning service opened successfully, sending initial device registration message 2022-10-21 10:41:20,680 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-RegisterTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.RegisterTask] - Authenticating with device provisioning service using x509 certificates 2022-10-21 10:41:21,603 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Waiting for device provisioning service to provision this device... 2022-10-21 10:41:21,605 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Current provisioning status: ASSIGNING 2022-10-21 10:41:24,868 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Device provisioning service assigned the device successfully IotHUb Uri : contoso-hub-2.azure-devices.net Device ID : device-01 2022-10-21 10:41:30,514 INFO (main) [com.microsoft.azure.sdk.iot.device.transport.ExponentialBackoffWithJitter] - NOTE: A new instance of ExponentialBackoffWithJitter has been created with the following properties. Retry Count: 2147483647, Min Backoff Interval: 100, Max Backoff Interval: 10000, Max Time Between Retries: 100, Fast Retry Enabled: true 2022-10-21 10:41:30,526 INFO (main) [com.microsoft.azure.sdk.iot.device.transport.ExponentialBackoffWithJitter] - NOTE: A new instance of ExponentialBackoffWithJitter has been created with the following properties. Retry Count: 2147483647, Min Backoff Interval: 100, Max Backoff Interval: 10000, Max Time Between Retries: 100, Fast Retry Enabled: true 2022-10-21 10:41:30,533 DEBUG (main) [com.microsoft.azure.sdk.iot.device.DeviceClient] - Initialized a DeviceClient instance using SDK version 2.1.2 2022-10-21 10:41:30,590 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection] - Opening MQTT connection... 2022-10-21 10:41:30,625 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sending MQTT CONNECT packet... 2022-10-21 10:41:31,452 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sent MQTT CONNECT packet was acknowledged 2022-10-21 10:41:31,453 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sending MQTT SUBSCRIBE packet for topic devices/device-01/messages/devicebound/# 2022-10-21 10:41:31,523 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sent MQTT SUBSCRIBE packet for topic devices/device-01/messages/devicebound/# was acknowledged 2022-10-21 10:41:31,525 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection] - MQTT connection opened successfully 2022-10-21 10:41:31,528 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - The connection to the IoT Hub has been established 2022-10-21 10:41:31,531 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Updating transport status to new status CONNECTED with reason CONNECTION_OK 2022-10-21 10:41:31,532 DEBUG (main) [com.microsoft.azure.sdk.iot.device.DeviceIO] - Starting worker threads 2022-10-21 10:41:31,535 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Invoking connection status callbacks with new status details 2022-10-21 10:41:31,536 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Client connection opened successfully 2022-10-21 10:41:31,537 INFO (main) [com.microsoft.azure.sdk.iot.device.DeviceClient] - Device client opened successfully Sending message from device to IoT Hub... 2022-10-21 10:41:31,539 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Message was queued to be sent later ( Message details: Correlation Id [aaaa0000-bb11-2222-33cc-444444dddddd] Message Id [aaaa0000-bb11-2222-33cc-444444dddddd] ) Press any key to exit... 2022-10-21 10:41:31,540 DEBUG (contoso-hub-2.azure-devices.net-device-01-d7c67552-Cxn0bd73809-420e-46fe-91ee-942520b775db-azure-iot-sdk-IotHubSendTask) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Sending message ( Message details: Correlation Id [aaaa0000-bb11-2222-33cc-444444dddddd] Message Id [aaaa0000-bb11-2222-33cc-444444dddddd] ) 2022-10-21 10:41:31,844 DEBUG (MQTT Call: device-01) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - IotHub message was acknowledged. Checking if there is record of sending this message ( Message details: Correlation Id [aaaa0000-bb11-2222-33cc-444444dddddd] Message Id [aaaa0000-bb11-2222-33cc-444444dddddd] ) 2022-10-21 10:41:31,846 DEBUG (contoso-hub-2.azure-devices.net-device-01-d7c67552-Cxn0bd73809-420e-46fe-91ee-942520b775db-azure-iot-sdk-IotHubSendTask) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Invoking the callback function for sent message, IoT Hub responded to message ( Message details: Correlation Id [aaaa0000-bb11-2222-33cc-444444dddddd] Message Id [aaaa0000-bb11-2222-33cc-444444dddddd] ) with status OK Message sent!
次の表に従って 2 番目のデバイス (
device-02
) の定数を更新し、リビルドし、サンプルをもう一度実行します。定数 使用するファイル leafPublicPem
./certs/device-02.cert.pem leafPrivateKey
private/device-02.key.pem
デバイス プロビジョニングの登録を確認する
登録グループの登録レコードを調べて、デバイスの登録の詳細を確認します。
Azure Portal でデバイス プロビジョニング サービス インスタンスに移動します。
[設定] メニューで [登録の管理] を選択します。
[登録グループ] を選択します。 以前に作成した X.509 登録グループ エントリが一覧に表示されます。
その登録エントリを選択します。 次に、[登録状態] の横にある [詳細] を選択して、登録グループを通じて登録されたデバイスを表示します。 各デバイスが割り当てられた IoT ハブ、デバイス ID、および登録された日付と時刻が一覧に表示されます。
いずれかのデバイスを選択すると、そのデバイスの詳細を確認できます。
IoT ハブでデバイスを確認するには:
Azure portalで、デバイスが割り当てられた IoT ハブに移動します。
[デバイス管理] メニューで、[デバイス] を選択します。
デバイスが正常にプロビジョニングされた場合は、デバイス ID (device-01 と device-02) が一覧に表示され、[状態] は [有効] に設定されます。 デバイスが表示されない場合は、[最新の情報に更新] を選択します。
リソースをクリーンアップする
テストを実施し、このデバイス クライアント サンプルの確認が完了したら、次の手順に従い、このチュートリアルで作成したリソースをすべて削除します。
- マシンに表示されているデバイス クライアント サンプルの出力ウィンドウを閉じます。
登録グループを削除する
Azure portal の左側のメニューから、 [すべてのリソース] を選択します。
DPS インスタンスを選択します。
[設定] メニューで [登録の管理] を選択します。
[登録グループ] タブを選択します。
このチュートリアルで使用した登録グループを選択します。
[登録の詳細] ページで、[登録状態] の横にある [詳細] を選択します。 次に、[デバイス ID] 列ヘッダーの横にあるチェック ボックスをオンにして、登録グループのすべての登録レコードを選択します。 ページの上部にある [削除] を選択して、登録レコードを削除します。
重要
登録グループを削除しても、関連付けられている登録レコードは削除されません。 これらの孤立したレコードは、DPS インスタンスの登録クォータにカウントされます。 このため、登録グループ自体を削除する前に、登録グループに関連付けられているすべての登録レコードを削除することをお勧めします。
[Manage enrollments] (登録の管理) ページに戻り、[登録グループ] タブが選択されていることを確認します。
このチュートリアルで使用した登録グループのグループ名の横にあるチェック ボックスをオンにします。
ページの上部で、[削除] を選択します。
DPS から登録済み CA 証明書を削除する
- DPS インスタンスの左側のメニューから [証明書] を選択します。 このチュートリアルでアップロードし、検証した証明書それぞれについて、証明書を選択して [削除] を選択し、選択した内容が正しいことを確認して削除します。
IoT Hub からデバイスの登録を削除する
Azure portal の左側のメニューから、 [すべてのリソース] を選択します。
IoT ハブを選択します。
[エクスプローラー] メニューで、 [IoT デバイス] を選択します。
このチュートリアルで登録したデバイスのデバイス ID の横にあるチェック ボックスをオンにします。 たとえば、device-01 や device-02 などです。
ページの上部で、[削除] を選択します。
次のステップ
このチュートリアルでは、登録グループを使って複数の X.509 デバイスを IoT ハブにプロビジョニングしました。 次に、複数のハブ間で IoT デバイスをプロビジョニングする方法について説明します。