X.509 証明書の構成証明のための Device Provisioning Service 登録グループをプログラムで作成する

この記事では、中間またはルート CA の X.509 証明書を使用する登録グループをプログラムで作成する方法について説明します。 登録グループは、Azure IoT Hub DPS サービス SDK とサンプル アプリケーションを使用して作成します。 登録グループでは、証明書チェーン内の共通の署名証明書を共有するデバイスに関してプロビジョニング サービスへのアクセスを制御します。 詳細については、X.509 証明書を使用してデバイス アクセスを制御する方法に関するページを参照してください。 Azure IoT Hub と Device Provisioning Service と共に X.509 証明書ベースの公開キー基盤 (PKI) を使用する方法について詳しくは、X.509 CA 証明書セキュリティの概要に関するページを参照してください。

前提条件

  • Windows ベースのマシンに .NET 6.0 SDK 以降をインストールします。 次のコマンドを使用してバージョンを確認してください。

    dotnet --info
    
  • 最新バージョンの Git をインストールします。 コマンド ウィンドウからアクセスできる環境変数に Git が追加されていることを確認します。 Git Bash (ローカル Git リポジトリとやりとりする際に使用できるコマンドライン アプリ) を含む、インストールする git ツールの最新バージョンについては、Software Freedom Conservancy の Git クライアント ツールに関するページを参照してください。

Note

この記事の手順は Windows コンピューターと Linux コンピューターの両方に利用できますが、この記事では Windows 開発コンピューターを使用します。

テスト証明書を作成する

X.509 証明書の構成証明を使用する登録グループは、ルート CA 証明書または中間証明書を使用するように構成できます。 通常は、中間証明書を使用するように登録グループを構成します。 中間証明書を使用することにより、同じルート CA 証明書で複数の中間証明書を生成または取り消すことができるため、柔軟性が向上します。

この記事では、ルート CA 証明書ファイルと中間 CA 証明書ファイルのいずれか (どちらも .pem 形式または .cer 形式) が必要です。 前者のファイルには、ルート CA の X.509 証明書の公開部分が含まれ、後者のファイルには、中間 CA の X.509 証明書の公開部分が含まれます。

ルート CA ファイルや中間 CA ファイルが既にある場合は、先に進み、ルートまたは中間 CA 証明書を追加して検証できます。

ルート CA ファイルや中間 CA ファイルがない場合、「X.509 証明書チェーンを作成する」の手順に従って、これらを作成してください。 この記事の手順を実行するためにデバイス証明書は必要ないため、「中間 CA 証明書を作成する」の手順を実行したら、そこで完了です。 完了すると、2 つの X.509 証明書ファイル (./certs/azure-iot-test-only.root.ca.cert.pem./certs/azure-iot-test-only.intermediate.cert.pem) が用意されます。

ルートまたは中間 CA 証明書を追加して検証する

X.509 証明書を使用する登録グループを介してプロビジョニングされるデバイスは、DPS で認証を行うときに証明書チェーン全体を提示します。 DPS で証明書チェーンを検証できるようにするために、登録グループに構成するルートまたは中間証明書は、検証済みの証明書であるか、またはデバイスがサービスで認証を行うときに提示する証明書チェーンの検証済み証明書にロールアップされるものである必要があります。

この記事では、ルート CA 証明書と、ルート CA が署名した中間 CA 証明書の両方があると仮定します。

  • ルート CA 証明書を使用する登録グループを作成する場合、ルート CA 証明書をアップロードして検証する必要があります。

  • 中間 CA 証明書を使用する登録グループを作成する場合、ルート CA 証明書または中間 CA 証明書をアップロードして検証できます。 (証明書チェーンに複数の中間 CA 証明書がある場合、作成する登録グループで使用するルート CA 証明書と中間証明書の間にある任意の中間証明書をアップロードして検証することもできます。)

ルートまたは中間 CA 証明書を Device Provisioning Service に追加して検証するには:

  1. Azure portal にサインインします。

  2. 左側のメニューまたはポータル ページで、 [すべてのリソース] を選択します。

  3. ご利用の Device Provisioning Service を選択します。

  4. [設定] メニューで [証明書] を選択します。

  5. 上部のメニューで、[+ 追加] を選択します。

  6. ルートまたは中間 CA 証明書の名前を入力し、.pem または .cer ファイルをアップロードします。

  7. [証明書の状態をアップロード時に確認済みに設定する] を選択します。

    DPS インスタンスへのルート CA 証明書の追加を示すスクリーンショット。

  8. [保存] を選択します。

プロビジョニング サービスの接続文字列を取得する

この記事のサンプルには、プロビジョニング サービスの接続文字列が必要です。 次の手順を使ってそれを取得します。

  1. Azure portal にサインインします。

  2. 左側のメニューまたはポータル ページで、 [すべてのリソース] を選択します。

  3. ご利用の Device Provisioning Service を選択します。

  4. [設定] メニューから、[共有アクセス ポリシー] を選択します。

  5. 使用するアクセス ポリシーを選択します。

  6. [アクセス ポリシー] パネルで、主キーの接続文字列をコピーして保存します。

    ポータル内のプロビジョニング サービス接続文字列の場所を示すスクリーンショット。

登録グループのサンプルを作成する

このセクションでは、登録グループをプロビジョニング サービスに追加する .NET Core コンソール アプリケーションを作成する方法について説明します。

  1. Windows コマンド プロンプトを開き、アプリを作成するフォルダーに移動します。

  2. コンソール プロジェクトを作成するために、次のコマンドを実行します。

    dotnet new console --framework net6.0 --use-program-main 
    
  3. DPS サービス SDK への参照を追加するために、次のコマンドを実行します。

    dotnet add package Microsoft.Azure.Devices.Provisioning.Service 
    

    この手順により、Azure IoT DPS サービス クライアント NuGet パッケージがダウンロード、インストールされ、このパッケージへの参照とその依存関係が追加されます。 このパッケージには、.NET サービス SDK のバイナリが含まれます。

  4. エディターで Program.cs ファイルを開きます。

  5. ファイルの先頭にある namespace ステートメントを以下の行に置き換えます。

    namespace CreateEnrollmentGroup;
    
  6. 次の using ステートメントを、ファイルの先頭の namespace ステートメントのに追加します。

    using System.Security.Cryptography.X509Certificates;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Provisioning.Service;
    
  7. Program クラスに次のフィールドを追加し、示されている変更を行います。

    private static string ProvisioningConnectionString = "{ProvisioningServiceConnectionString}";
    private static string EnrollmentGroupId = "enrollmentgrouptest";
    private static string X509RootCertPath = @"{Path to a .cer or .pem file for a verified root CA or intermediate CA X.509 certificate}";
    
    • ProvisioningServiceConnectionString プレースホルダーの値を、前のセクションでコピーしたプロビジョニング サービスの接続文字列に置き換えます。

    • プレースホルダー X509RootCertPath の値は、.pem ファイルまたは .cer ファイルへのパスに置き換えます。 このファイルは、前にアップロードされ、プロビジョニング サービスで検証されたルート CA の X.509 証明書、それ自体がアップロードされて検証された中間証明書、またはその署名チェーン内の証明書がアップロードされて検証された中間証明書の公開部分を表します。

    • EnrollmentGroupId の値は、必要に応じて変更することができます。 文字列に含めることができるのは、小文字とハイフンのみです。

    重要

    運用コードでは、セキュリティに関する次の考慮事項に注意してください。

    • プロビジョニング サービス管理者の接続文字列のハードコーディングは、セキュリティのベスト プラクティスに反しています。 代わりに、接続文字列は安全な方法で保持する必要があります (例: セキュリティ保護された構成ファイル内またはレジストリ内)。
    • 必ず署名証明書の公開部分のみをアップロードしてください。 プロビジョニング サービスへの秘密キーが含まれた .pfx (PKCS12) ファイルまたは .pem ファイルは、決してアップロードしないでください。
  8. 次のメソッドを Program クラスに追加します。 このコードにより、EnrollmentGroup エントリが作成され、ProvisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync メソッドが呼び出されて登録グループがプロビジョニング サービスに追加されます。

    public static async Task RunSample()
    {
        Console.WriteLine("Starting sample...");
    
        using (ProvisioningServiceClient provisioningServiceClient =
                ProvisioningServiceClient.CreateFromConnectionString(ProvisioningConnectionString))
        {
            #region Create a new enrollmentGroup config
            Console.WriteLine("\nCreating a new enrollmentGroup...");
            var certificate = new X509Certificate2(X509RootCertPath);
            Attestation attestation = X509Attestation.CreateFromRootCertificates(certificate);
            EnrollmentGroup enrollmentGroup =
                    new EnrollmentGroup(
                            EnrollmentGroupId,
                            attestation)
                    {
                        ProvisioningStatus = ProvisioningStatus.Enabled
                    };
            Console.WriteLine(enrollmentGroup);
            #endregion
    
            #region Create the enrollmentGroup
            Console.WriteLine("\nAdding new enrollmentGroup...");
            EnrollmentGroup enrollmentGroupResult =
                await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(enrollmentGroup).ConfigureAwait(false);
            Console.WriteLine("\nEnrollmentGroup created with success.");
            Console.WriteLine(enrollmentGroupResult);
            #endregion
    
        }
    }
    
  9. 最後に、Main メソッドを次の行に置き換えます。

    static async Task Main(string[] args)
    {
        await RunSample();
        Console.WriteLine("\nHit <Enter> to exit ...");
        Console.ReadLine();
    }
    
  10. 変更を保存します。

このセクションでは、登録グループをプロビジョニング サービスに追加する Node.js スクリプトを作成する方法を示します。

  1. 作業フォルダーのコマンド ウィンドウから次のコマンドを実行します。

    npm install azure-iot-provisioning-service
    

    この手順により、Azure IoT DPS サービス クライアント パッケージがダウンロード、インストールされ、このパッケージへの参照とその依存関係が追加されます。 このパッケージには、Node.js サービス SDK のバイナリが含まれます。

  2. テキスト エディターを使用して、作業フォルダーに create_enrollment_group.js ファイルを作成します。 次のコードをファイルに追加して保存します。

        'use strict';
        var fs = require('fs');
    
        var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient;
    
        var serviceClient = provisioningServiceClient.fromConnectionString(process.argv[2]);
    
        var enrollment = {
          enrollmentGroupId: 'first',
          attestation: {
            type: 'x509',
            x509: {
              signingCertificates: {
                primary: {
                  certificate: fs.readFileSync(process.argv[3], 'utf-8').toString()
                }
              }
            }
          },
          provisioningStatus: 'disabled'
        };
    
        serviceClient.createOrUpdateEnrollmentGroup(enrollment, function(err, enrollmentResponse) {
          if (err) {
            console.log('error creating the group enrollment: ' + err);
          } else {
            console.log("enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2));
            enrollmentResponse.provisioningStatus = 'enabled';
            serviceClient.createOrUpdateEnrollmentGroup(enrollmentResponse, function(err, enrollmentResponse) {
              if (err) {
                console.log('error updating the group enrollment: ' + err);
              } else {
                console.log("updated enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2));
              }
            });
          }
        });
    

  1. Windows コマンド プロンプトを開きます。

  2. Java Service SDK を使用して、デバイス登録コード サンプルの GitHub リポジトリを複製します。

    git clone https://github.com/Azure/azure-iot-sdk-java.git --recursive
    
  3. リポジトリをダウンロードした場所から、サンプル フォルダーに移動します。

    cd azure-iot-sdk-java\provisioning\provisioning-service-client-samples\service-enrollment-group-sample 
    
  4. 任意のエディターでファイル /src/main/java/samples/com/microsoft/azure/sdk/iot/ServiceEnrollmentGroupSample.java を開きます。

  5. [Provisioning Connection String] を、「プロビジョニング サービスの接続文字列を取得する」でコピーしておいた接続文字列に置き換えます。

  6. PUBLIC_KEY_CERTIFICATE_STRING 定数文字列を、ルートまたは中間 CA 証明書 .pem ファイルの値に置き換えます。 このファイルは、前にアップロードされ、プロビジョニング サービスで検証されたルート CA の X.509 証明書、それ自体がアップロードされて検証された中間証明書、またはその署名チェーン内の証明書がアップロードされて検証された中間証明書の公開部分を表します。

    証明書のテキストの構文は、次のパターンに従う必要があります。余分なスペースや文字が追加されないようにしてください。

    private static final String PUBLIC_KEY_CERTIFICATE_STRING = 
            "-----BEGIN CERTIFICATE-----\n" +
            "MIIFOjCCAyKgAwIBAgIJAPzMa6s7mj7+MA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV\n" +
                ...
            "MDMwWhcNMjAxMTIyMjEzMDMwWjAqMSgwJgYDVQQDDB9BenVyZSBJb1QgSHViIENB\n" +
            "-----END CERTIFICATE-----";
    

    この文字列値を手動で更新すると、エラーが発生する可能性があります。 適切な構文を生成するために、次のコマンドをコピーし、Git Bash プロンプトに貼り付け、your-cert.pem をお使いの証明書ファイルの場所に置き換え、ENTER キーを押すことができます。 このコマンドは PUBLIC_KEY_CERTIFICATE_STRING 文字列定数値の構文を生成して、出力に書き込みます。

    sed 's/^/"/;$ !s/$/\\n" +/;$ s/$/"/' your-cert.pem
    

    定数値の証明書の出力テキストをコピーして貼り付けます。

    重要

    運用コードでは、セキュリティに関する次の考慮事項に注意してください。

    • プロビジョニング サービス管理者の接続文字列のハードコーディングは、セキュリティのベスト プラクティスに反しています。 代わりに、接続文字列は安全な方法で保持する必要があります (例: セキュリティ保護された構成ファイル内またはレジストリ内)。
    • 必ず署名証明書の公開部分のみをアップロードしてください。 プロビジョニング サービスへの秘密キーが含まれた .pfx (PKCS12) ファイルまたは .pem ファイルは、決してアップロードしないでください。
  7. このサンプルでは、登録グループでデバイスをプロビジョニングする先の IoT Hub を設定できます。 これは、プロビジョニング サービスに以前にリンクされた IoT Hub である必要があります。 この記事では、DPS が既定の割り当てポリシー (加重が均等に分布) に従って、リンクされたハブから選択できるようにします。 ファイル内の次のステートメントをコメント アウトします。

    enrollmentGroup.setIotHubHostName(IOTHUB_HOST_NAME);                // Optional parameter.
    
  8. このサンプル コードにより、X.509 デバイスの登録グループが作成、更新、照会、削除されます。 Azure portal で登録グループの作成が成功したことを確認するために、ファイルの末尾近くにある次のコード行をコメント アウトします。

    // ************************************** Delete info of enrollmentGroup ***************************************
    System.out.println("\nDelete the enrollmentGroup...");
    provisioningServiceClient.deleteEnrollmentGroup(enrollmentGroupId);
    
  9. ServiceEnrollmentGroupSample.java ファイルを保存します。

登録グループのサンプルを実行する

  1. サンプルを実行します。

    dotnet run
    
  2. 作成が正常に完了すると、コマンド ウィンドウに新しい登録グループのプロパティが表示されます。

  1. コマンド プロンプトで、次のコマンドを実行します。 コマンド引数は引用符で囲み、<connection string> は前のセクションでコピーした接続文字列に置き換え、<certificate .pem file> は証明書 .pem ファイルへのパスに置き換えます。 このファイルは、前にアップロードされ、プロビジョニング サービスで検証されたルート CA の X.509 証明書、それ自体がアップロードされて検証された中間証明書、またはその署名チェーン内の証明書がアップロードされて検証された中間証明書の公開部分を表します。

    node create_enrollment_group.js "<connection string>" "<certificate .pem file>"
    
  2. 作成が正常に完了すると、コマンド ウィンドウに新しい登録グループのプロパティが表示されます。

  1. コマンド プロンプトで、azure-iot-sdk-java\provisioning\provisioning-service-client-samples\service-enrollment-group-sample フォルダーから次のコマンドを実行してサンプルをビルドします。

    mvn install -DskipTests
    

    このコマンドにより、Azure IoT DPS サービス クライアント Maven パッケージがマシンにダウンロードされ、サンプルがビルドされます。 このパッケージには、Java サービス SDK のバイナリが含まれます。

  2. target フィルダーに切り替えてサンプルを実行します。 前の手順のビルドにより、target フォルダー内に .jar ファイルが出力されます。このファイルのファイル形式は provisioning-x509-sample-{version}-with-deps.jar (例: provisioning-x509-sample-1.8.1-with-deps.jar) です。 バージョンは下のコマンドで置き換えが必要になる場合があります。

    cd target
    java -jar ./service-enrollment-group-sample-1.8.1-with-deps.jar
    
  3. 作成が正常に完了すると、コマンド ウィンドウに新しい登録グループのプロパティが表示されます。

登録グループが作成されていることを確認するには:

  1. Azure portal で Device Provisioning Service インスタンスに移動します。

  2. [設定] メニューで [登録の管理] を選択します。

  3. [登録グループ] タブを選択します。サンプルで使用した登録グループ ID に対応する新しい登録エントリが表示されます。

ポータルのスクリーンショット。新しく作成された登録グループが表示されています。

ポータルのスクリーンショット。新しく作成された登録グループが表示されています。

ポータルのスクリーンショット。新しく作成された登録グループが表示されています。

リソースをクリーンアップする

Azure IoT Hub Device Provisioning Service のチュートリアルに進む場合、この記事で作成したリソースはクリーンアップしないでください。 それ以外の場合は、次の手順を使用して、この記事で作成したすべてのリソースを削除してください。

  1. コンピューター上のサンプル出力ウィンドウを閉じます。

  2. Azure portal の左側のメニューから、 [すべてのリソース] を選択します。

  3. ご利用の Device Provisioning Service を選択します。

  4. 左側のメニューの [設定] で、[登録の管理] を選択します。

  5. [登録グループ] タブを選択します。

  6. この記事で作成した登録グループの[グループ名]の横にあるチェック ボックスをオンにします。

  7. ページの上部で、[削除] を選択します。

  8. Azure portal の Device Provisioning Service から、左側のメニューの [設定][証明書] を選択します。

  9. この記事でアップロードした証明書を選択します。

  10. [証明書の詳細] の上部で、[削除] を選択します。

証明書ツール

Azure IoT C SDK には、証明書の作成と管理に役立つスクリプトがあります。 詳しくは、サンプルとチュートリアルのテスト CA 証明書の管理に関するページを参照してください。

Azure IoT Node.js SDK には、証明書の作成と管理に役立つスクリプトがあります。 詳しくは、Azure IoT Device Provisioning Device SDK for Node.js のツールに関するページを参照してください。

Azure IoT C SDK で使用できるツールも使用できます。 詳しくは、サンプルとチュートリアルのテスト CA 証明書の管理に関するページを参照してください。

Azure IoT Java SDK には、証明書の作成と管理に役立つテスト ツールが含まれています。 詳しくは、DICE エミュレーターを使用した X509 証明書ジェネレーターに関するページを参照してください。

次のステップ

この記事では、Azure IoT Hub Device Provisioning Service を使用して X.509 中間またはルート CA 証明書の登録グループを作成しました。 さらに学習するために、次のリンクを確認してください。