株式会社セキュアイノベーション

    Menu

    セキュリティコラム

    • ネットワーク

    公開:2025.04.16 09:35 | 更新: 2025.04.16 12:35

    C#でAWS IoT Coreへのクレーム証明書を用いたフリートプロビジョニング

    セキュアイノベーション:セキュリティブログ「C#でAWS IoT Coreへのクレーム証明書を用いたフリートプロビジョニング」セキュアイノベーション:セキュリティブログ「C#でAWS IoT Coreへのクレーム証明書を用いたフリートプロビジョニング」

    はじめに

    執筆者は社内で製品開発をしていますが、今回は少し技術的な内容を掘り下げていきたいと思います。
    AWS IoT Core を活用する中で、「フリートプロビジョニング(Fleet Provisioning)」という言葉を耳にしたことがあるかもしれません。

    これは、大量のデバイスを一括して安全に登録・管理するための機構ですが、多くの開発記事では JavaScript や Python を用いた例が主流で、C# に関する情報はほとんど見当たりません。
    ※英語圏のフォーラムや GitHub Issues を徘徊しても、確たる情報には辿り着けませんでした。

    そこで今回は、C#での AWS IoT Core へのクレーム証明書を用いたフリートプロビジョニングを実現する方法を共有いたします。
    WindowsのエージェントソフトウェアとしてC#での開発を行いたかったのですが、公式SDKにC#向けのフリートプロビジョニングサポートがないのが現実。ここが本記事の肝となる部分です。

    ※本記事内容に関する出典・参考: Amazon Web Services

    INDEX

    はじめに
    フリートプロビジョニングの基礎知識
    C#での実装アプローチ(実例付き)
     ┗使用した技術スタック
     ┗プロビジョニングの流れ
     ┗実装例(抜粋・要点)
     ┗実装のポイントと注意点
    開発中のつまづきポイント
    おわりに

    参考リンク

    フリートプロビジョニングの基礎知識

    まず前提として、フリートプロビジョニングには以下のような要素が絡みます。

    • テンプレートの作成(Provisioning Template)
    • IAMロールとポリシーの設定
    • デバイスの登録および証明書の取得

    今回は、デバイスの登録および証明書の取得について解説します。
    デバイスは事前に配布している一時的な証明書(プロビジョニングクレーム証明書)を利用してAWS IoT Coreと複数回やり取りを行い、新しいデバイス固有の証明書(デバイス証明書)で通信を行います。
    複数回のやり取りについて、Python等であれば 公式のSDKを使って数行で完結する処理も、C#ではゴリゴリ書いていく必要があります。

    やり取りやフリートプロビジョニングの詳細については下記のAmazon Web Services ブログの「Fleet Provisioning の紹介」を参考にしてください。

    ※本記事内容に関する出典・参考: Amazon Web Services ブログ「量産デバイスや大量のデバイスに個別の認証情報を発行する方法について」

      C#での実装アプローチ(実例付き)

    使用した技術スタック

    • MQTT通信:MQTTnet ライブラリ(TLS証明書認証対応)
    • 証明書管理:X509Certificate2 によるPFXの読み書き
    • 独自ユーティリティ:証明書保存、設定管理などを分離

    プロビジョニングの流れ

    プロビジョニングの流れ(図解イメージ)
[クレーム証明書でMQTT接続]
        ↓
[$aws/certificates/create/json にPublish]
        ↓
[$aws/certificates/create/json/acceptedで証明書・tokenを受信]
        ↓
[$aws/provisioning-templates/<テンプレート名>/provision/json にtoken付きでPublish]
        ↓
[$aws/provisioning-templates/<テンプレート名>/provision/json/acceptedでプロビジョニング情報受信]
        ↓
[PFX保存・Config反映 → 完了]

    実装例(抜粋・要点)

    以下のコードでは、AWS IoT Core と MQTT over TLS を用いて、C#でフリートプロビジョニングを行う処理を実装しています。

    1. MQTT接続(クレーム証明書利用)

    var claimCertPass = "<クレーム証明書のパスワード>";
    var cert = new X509Certificate2(claimCertPath, claimCertPass);
    
    var options = new MqttClientOptionsBuilder()
        .WithClientId(deviceId)
        .WithTcpServer(domain,_port)
        .WithTls(new MqttClientOptionsBuilderTlsParameters
        {
            UseTls = true,
            Certificates = new List<X509Certificate> { cert },
            AllowUntrustedCertificates = true
        })
        .WithCommunicationTimeout(TimeSpan.FromSeconds(60))
        .Build();
    
    client.ConnectAsync(options).GetAwaiter().GetResult();
    

    2. デバイス証明書作成のリクエスト送信

    client.PublishAsync(CreatePublishMessage("$aws/certificates/create/json", []));

    3. 証明書取得と保存(PFX形式で)

    // $aws/certificates/create/json/acceptedを受信後
    var response = JsonSerializer.Deserialize<CreateKeysAndCertificateResponse>(payload);
    Pfx.ExportPfx(response, deviceId, OutputPfxPath);
    return response.CertificateOwnershipToken;

    4. フリートプロビジョニングのリクエスト送信

    var payloadObj = new
    {
        certificateOwnershipToken = token,
        parameters = new
        {
            deviceId = _deviceId,
            serial = AppConfig.Load().SerialNumber,
        },
    };
    
    var payload = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(payloadObj));
    client.PublishAsync(CreatePublishMessage("$aws/provisioning-templates/<テンプレート名>/provision/json", payload));
    

    5. プロビジョニング結果の取得と設定保存

    var response = JsonSerializer.Deserialize<ProvisioningAcceptedResponse>(messagePayload);
    if (response?.DeviceConfiguration?.CompanyId != null)
    {
        var codex = AppConfig.Load();
        codex.CompanyId = response.DeviceConfiguration.CompanyId;
        AppConfig.Save(codex);
    }

    実装のポイントと注意点

    項 目解 説
    MQTT over TLSクレーム証明書により初回接続。CAやパスフレーズを適切に管理する必要あり。
    QoS設定MQTTの信頼性確保のため QoS 1 を設定(AtLeastOnceQoS)
    エラーハンドリング/rejected トピックを捕捉し、不正な証明書は削除してフェイルセーフを確保する必要あり。

    このように、公式SDKが未対応であっても、MQTTによる直接通信を行うことで、C#でもフリートプロビジョニングは実現出来ました。

    開発中のつまずきポイント

    • 当初、クレーム証明書とデバイス証明書の違いが十分に理解できていなかった。
    • accepted等のレスポンスの受信で同じ内容が2度受信されることがある。
    • AtLeastOnceQoSを設定しないとIoT Core側と通信できない。

    おわりに

    本記事のアプローチを土台として、C#だけでフリートプロビジョニング機能を組み込むことが可能になります。
    記事のアクセス状況次第では、開発中のソースコードを分離・整理し、GitHubでの公開を予定しています。

    参考資料

    最新のコラム記事

    LOADING...

    セキュアイノベーション サービス一覧

    ネットワーク・サーバー

    Webサイトを守る

    ヘルプデスク・サポート