Azure IoT 中级(4)-(案例2)使用DPS通过对称密钥进行设备组注册
视频讲解:
您可以在B站观看视频讲解:https://www.bilibili.com/video/av92782084/
图文讲解:
1. 在DPS添加组注册:
注意:组注册中,没有注册ID的概念,也没有Device ID的概念。
机制
有三种:x509证书,对称密钥
在本例中,我们使用对称密钥方式以便我们快速理解和验证组注册的业务逻辑;
密钥我们采用自动生成,当然也可以手动输入符合要求的自定义密钥;
注意:本文中使用对称密钥方式做演示,后续章节介绍X509证书的方式,证书也是推荐的海量设备方案中应用的方案。
如何分配设备到中心
- 最低延迟:将设备预配到具有最低延迟的 IoT 中心,注意最低延迟不是指地理位置,例如中国北部的设备根据网络情况可能出现分配到中国东部IoT Hub的情况。
- 均匀加权分发(默认):链接的 IoT 中心等可能地获得预配到它们的设备。 此设置为默认设置。 如果只将设备预配到一个 IoT 中心,则可以保留此设置。
- 通过注册列表进行静态配置:注册列表中所需 IoT 中心的规范优先于设备预配服务级别的分配策略。
- 使用Azure Function(自定义):该方案可以使用自定义逻辑判断分发到哪个IoT Hub。
在本例中,我们只配置了一个IoT Hub,因此采用默认的均匀加权即可。
初始设备孪生状态
例如可以设置版本号为 1.11,会按照device twin的逻辑进行版本升级;
添加之后的状态为:
注册记录为空:
2.准备示例代码
项目中使用的示例代码,https://codeload.github.com/Azure-Samples/azure-iot-samples-csharp/zip/master
关键处请参加如下代码中的中文注释:
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Azure.Devices.Provisioning.Client;
using Microsoft.Azure.Devices.Provisioning.Client.Samples;
using Microsoft.Azure.Devices.Provisioning.Client.Transport;
using Microsoft.Azure.Devices.Shared;
using System;
using System.Security.Cryptography;
using System.Text;
namespace SymmetricKeySample
{
class Program
{
// The Provisioning Hub IDScope.
// For this sample either:
// - pass this value as a command-prompt argument
// - set the DPS_IDSCOPE environment variable
// - create a launchSettings.json (see launchSettings.json.template) containing the variable
//private static string s_idScope = Environment.GetEnvironmentVariable("DPS_IDSCOPE");
private static string s_idScope = "此处需要修改成dps的ID";
// In your Device Provisioning Service please go to "Manage enrollments" and select "Individual Enrollments".
// Select "Add individual enrollment" then fill in the following:
// Mechanism: Symmetric Key
// Auto-generate keys should be checked
// DeviceID: iothubSymmetricKeydevice1
// Symmetric Keys may also be used for enrollment groups.
// In your Device Provisioning Service please go to "Manage enrollments" and select "Enrollment Groups".
// Select "Add enrollment group" then fill in the following:
// Group name: <your group name>
// Attestation Type: Symmetric Key
// Auto-generate keys should be checked
// You may also change other enrollment group parameters according to your needs
//private const string GlobalDeviceEndpoint = "global.azure-devices-provisioning.net";
//此处应该改成中国的终结点.CN结尾
private const string GlobalDeviceEndpoint = "global.azure-devices-provisioning.cn";
//These are the two keys that belong to your enrollment group.
// Leave them blank if you want to try this sample for an individual enrollment instead
private const string enrollmentGroupPrimaryKey = "仅当使用组注册时,必须填写此值";
private const string enrollmentGroupSecondaryKey = "仅当使用组注册时,必须填写此值";
//registration id for enrollment groups can be chosen arbitrarily and do not require any portal setup.
//The chosen value will become the provisioned device's device id.
//
//registration id for individual enrollments must be retrieved from the portal and will be unrelated to the provioned
//device's device id
//
//This field is mandatory to provide for this sample
private static string registrationId = "对于组注册,此处为待注册的设备DeviceID,通常填写诸如MAC地址等唯一值";
//These are the two keys that belong to your individual enrollment.
// Leave them blank if you want to try this sample for an individual enrollment instead
private const string individualEnrollmentPrimaryKey = "";
private const string individualEnrollmentSecondaryKey = "";
public static int Main(string[] args)
{
if (string.IsNullOrWhiteSpace(s_idScope) && (args.Length > 0))
{
s_idScope = args[0];
}
if (string.IsNullOrWhiteSpace(s_idScope))
{
Console.WriteLine("ProvisioningDeviceClientSymmetricKey <IDScope>");
return 1;
}
string primaryKey = "";
string secondaryKey = "";
if (!String.IsNullOrEmpty(registrationId) && !String.IsNullOrEmpty(enrollmentGroupPrimaryKey) && !String.IsNullOrEmpty(enrollmentGroupSecondaryKey))
{
//Group enrollment flow, the primary and secondary keys are derived from the enrollment group keys and from the desired registration id
//注意,此处的primaryKey和secondryKey即IoT Hub中新增Device 的primaryKey和secondryKey
primaryKey = ComputeDerivedSymmetricKey(Convert.FromBase64String(enrollmentGroupPrimaryKey), registrationId);
secondaryKey = ComputeDerivedSymmetricKey(Convert.FromBase64String(enrollmentGroupSecondaryKey), registrationId);
}
else if (!String.IsNullOrEmpty(registrationId) && !String.IsNullOrEmpty(individualEnrollmentPrimaryKey) && !String.IsNullOrEmpty(individualEnrollmentSecondaryKey))
{
//Individual enrollment flow, the primary and secondary keys are the same as the individual enrollment keys
primaryKey = individualEnrollmentPrimaryKey;
secondaryKey = individualEnrollmentSecondaryKey;
}
else
{
Console.WriteLine("Invalid configuration provided, must provide group enrollment keys or individual enrollment keys");
return -1;
}
using (var security = new SecurityProviderSymmetricKey(registrationId, primaryKey, secondaryKey))
// Select one of the available transports:
// To optimize for size, reference only the protocols used by your application.
using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly))
// using (var transport = new ProvisioningTransportHandlerHttp())
// using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
// using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly))
{
ProvisioningDeviceClient provClient =
ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, s_idScope, security, transport);
var sample = new ProvisioningDeviceClientSample(provClient, security);
sample.RunSampleAsync().GetAwaiter().GetResult();
}
Console.WriteLine("Enter any key to exit");
Console.ReadLine();
return 0;
}
/// <summary>
/// Generate the derived symmetric key for the provisioned device from the enrollment group symmetric key used in attestation
/// </summary>
/// <param name="masterKey">Symmetric key enrollment group primary/secondary key value</param>
/// <param name="registrationId">the registration id to create</param>
/// <returns>the primary/secondary key for the member of the enrollment group</returns>
public static string ComputeDerivedSymmetricKey(byte[] masterKey, string registrationId)
{
using (var hmac = new HMACSHA256(masterKey))
{
return Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(registrationId)));
}
}
}
}
3.运行程序,得到分配的IoT Hub名称以及DeviceID
设备侧程序可以得到IoT Hub的名称,设备的ID,加上代码里的key,则具备了连接IoT Hub的所有参数,此时可以直接连接到IoT Hub。
此时,可以在组注册中的注册列表中看到对应的注册记录:
此时,在IoT Hub中能够看到由DPS注册过来的Device:
将代码中的 private static string registrationId = "对于组注册,此处为待注册的设备DeviceID,通常填写诸如MAC地址等唯一值"; 替换,可以通过DPS的这个组注册添加多台设备到IoT Hub中:
声明:
本站所有内容仅代表个人观点,如与官文档冲突,请以官方文档为准,如有指正/咨询/意见/建议,请直接在51azure.cloud留言。
点击可查阅本站最新 《文章分类目录》
欢迎关注公众号“云计算实战”,接收最新文章推送。