2016年11月11日金曜日

IoT Hubでデバイスを認証させる方法

IoT Hub SDKを使って、IoT Hubに接続するデバイスを認証させることができます。方式としては
・セキュリティトークン
・X.509証明書
の2パターンになります。

セキュリティトークンを使う場合、セキュリティトークンをデバイス対称キーで署名するか、共有アクセスポリシーキーで署名するか、の2パターンになるのですが、共有アクセスポリシーキーで署名するケース(SASトークン)が多いので、ここでは
・SASトークン
・X.509証明書
の2パターンによる認証方法のコード例を示します。なお、コードはIoT Hubのチュートリアルからの変更点または注意点のみを記載します。

SASトークンによる認証:
以下のコードにてデバイスを登録します。
// RegistryManagerを生成
RegistryManager registryManager =     
    RegistryManager.CreateFromConnectionString("<IoT Hubへの接続文字列>");

// デバイスの登録
var device = new Device ("<デバイスID>");
device = await registryManager.AddDeviceAsync(device);

セキュリティトークンを使用するのがデフォルトの認証方式なので、認証方法を指定する必要はありません。

デバイスからIoT Hubに送信するときには、以下のコードにてSASトークンを生成し、デバイスからデータを送信します。
// SASトークンの生成
var sasToken = new SharedAccessSignatureBuilder()
    {
         KeyName = "<共有アクセスポリシー名>",
         Key = "<共有アクセスポリシーのアクセスキー>",
         Target = "<IoT Hubホスト名>" + "/devices/" + "<デバイスID>",
          TimeToLive = TimeSpan.FromDays(Convert.ToDouble("<有効期間>"))
    }.ToSignature();

// SASトークンを使用して、HTTPプロトコルで接続するDeviceClientインスタンスを作成
var authMethod = new DeviceAuthenticationWithToken("<デバイスID>", sasToken);
var deviceClient 
    = DeviceClient.Create("<IoT Hubホスト名>", authMethod, TransportType.Http1);


X.509証明書による認証:
以下のコードにてデバイスを登録します。デバイス登録時に、X.509証明書の拇印を指定します。
// RegistryManagerを生成
RegistryManager registryManager =     
    RegistryManager.CreateFromConnectionString("<IoT Hubへの接続文字列>");

// デバイスの登録
var device = new Device ("<デバイスID>") {
    Authentication = new AuthenticationMechanism()
    {
         // 拇印の指定
         X509Thumbprint = new X509Thumbprint()
             {
                 PrimaryThumbprint = "<X.509証明書の拇印>"
             }
    }
};
device = await registryManager.AddDeviceAsync(device);


デバイスからIoT Hubに送信するときには、以下のコードにてX.509証明書をロードし、デバイスからデータを送信します。
// X.509証明書を使用して、HTTPプロトコルで接続するDeviceClientインスタンスを作成
var x509Certificate = new X509Certificate2("<X.509証明書へのパス>");
var authMethod 
    = new DeviceAuthenticationWithX509Certificate("<デバイスID>", x509Certificate);
var deviceClient 
    = DeviceClient.Create("<IoT Hubホスト名>", authMethod, TransportType.Http1);