快速入门:预配模拟的 TPM 设备
在本快速入门中,你将在 Windows 计算机上创建一个模拟设备。 模拟设备将被配置为使用受信任平台模块 (TPM) 证明机制进行身份验证。 在配置了设备后,你将使用 Azure IoT 中心设备预配服务将其预配到 IoT 中心。 然后将使用示例代码在设备预配服务实例中注册设备。
如果不熟悉预配过程,请查看预配概述。 另外,在继续操作之前,请确保已完成通过 Azure 门户设置 IoT 中心设备预配服务中的步骤。
Azure IoT 设备预配服务支持两类注册:
本文演示单个注册。
先决条件
如果没有 Azure 订阅,请在开始前创建一个试用版订阅。
完成通过 Azure 门户设置 IoT 中心设备预配服务中的步骤。
以下先决条件适用于 Windows 开发环境。 对于 Linux 或 macOS,请参阅 SDK 文档的准备开发环境中的相应部分。
- Visual Studio 2019,已启用“使用 C++ 的桌面开发”工作负载。 Visual Studio 2015 和 Visual Studio 2017 也受支持。
在基于 Windows 的计算机上安装 .NET Core SDK 6.0 或更高版本。 可使用以下命令来检查你的版本。
dotnet --info
- 安装 Node.js v4.0+。
在计算机上安装 Java SE 开发工具包 8 或更高版本。
下载并安装 Maven。
- 安装最新版本的 Git。 确保将 Git 添加到可供命令窗口访问的环境变量。 请参阅软件自由保护组织提供的 Git 客户端工具,了解要安装的最新版
git
工具,其中包括 Git Bash,这是一个命令行应用,可以用来与本地 Git 存储库交互。
准备开发环境
在本部分,你将准备一个用于生成 Azure IoT C SDK 和 TPM 设备模拟器示例的开发环境。
下载最新的 CMake 生成系统。
重要
在开始
CMake
安装之前,请确认在计算机上安装 Visual Studio 必备组件(Visual Studio 和“使用 C++ 的桌面开发”工作负载)。 满足先决条件并验证下载内容后,安装 CMake 生成系统。 另请注意旧版本的 CMake 生成系统无法生成本文中使用的解决方案文件。 请确保使用最新版本的 CMake。打开 Web 浏览器,转到 Azure IoT C SDK 发布页。
选择页面顶部的“标记”选项卡。
复制最新版 Azure IoT C SDK 的标记名称。
打开命令提示符或 Git Bash shell。 运行以下命令,以克隆最新版本的适用于 C 的 Azure IoT 设备 SDK GitHub 存储库。 请将
<release-tag>
替换为在上一步骤中复制的标记,例如:lts_01_2023
。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
打开 Git CMD 或 Git Bash 命令行环境。
使用以下命令克隆适用于 C# 的 Azure IoT SDK GitHub 存储库:
git clone https://github.com/Azure/azure-iot-sdk-csharp.git
打开 Git CMD 或 Git Bash 命令行环境。
使用以下命令克隆 azure-utpm-c GitHub 存储库:
git clone https://github.com/Azure/azure-utpm-c.git --recursive
打开 Git CMD 或 Git Bash 命令行环境。
使用以下命令克隆 Java GitHub 存储库:
git clone https://github.com/Azure/azure-iot-sdk-java.git --recursive
生成并运行 TPM 设备模拟器
在本部分中,你将生成并运行 TPM 模拟器。 此模拟器通过端口 2321 和 2322 上的套接字进行侦听。 请不要关闭命令窗口。 本快速入门自始至终都需让该模拟器保持运行状态。
运行以下命令以生成包含 TPM 设备模拟器示例代码的 Azure IoT C SDK。 在
cmake
目录中生成模拟设备的 Visual Studio 解决方案。 此示例通过共享访问签名 (SAS) 令牌身份验证提供 TPM 证明机制。cmake -Duse_prov_client:BOOL=ON -Duse_tpm_simulator:BOOL=ON ..
提示
如果
cmake
找不到 C++ 编译器,则可能会在运行以上命令时出现生成错误。 如果出现这种情况,请尝试在 Visual Studio 命令提示符窗口中运行该命令。生成成功后,最后的几个输出行如下所示:
$ cmake -Duse_prov_client:BOOL=ON .. -- Building for: Visual Studio 16 2019 -- The C compiler identification is MSVC 19.23.28107.0 -- The CXX compiler identification is MSVC 19.23.28107.0 ... -- Configuring done -- Generating done -- Build files have been written to: C:/code/azure-iot-sdk-c/cmake
转到克隆 Git 存储库的根文件夹。
使用下面所示的路径运行 TPM 模拟器。
cd .. .\provisioning_client\deps\utpm\tools\tpm_simulator\Simulator.exe
模拟器不会显示任何输出。 请让它继续模拟 TPM 设备。
转到 GitHub 根文件夹。
对模拟设备运行 TPM。
.\azure-utpm-c\tools\tpm_simulator\Simulator.exe
新建名为 registerdevice 的空文件夹。 在 registerdevice 文件夹的命令提示符处,使用以下命令创建 package.json 文件(确保回答
npm
提问的所有问题,如果默认值适合,则接受默认值):npm init
安装以下前提包:
npm install node-gyp -g npm install ffi-napi -g
注意
安装上述包时存在一些已知问题。 若要解决这些问题,请使用命令提示符在“以管理员身份运行”模式下运行
npm install --global --production windows-build-tools
,在将路径替换为已安装版本后运行SET VCTargetsPath=C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140
,然后重新运行上述安装命令。在 registerdevice 文件夹中的命令提示符处运行以下命令来安装所需的包:
npm install --save azure-iot-device azure-iot-device-mqtt azure-iot-security-tpm azure-iot-provisioning-device-http azure-iot-provisioning-device
该命令安装以下包:
适用于 TPM 的安全客户端:
azure-iot-security-tpm
设备的传输,用于连接到设备预配服务:
azure-iot-provisioning-device-http
或azure-iot-provisioning-device-amqp
使用传输的客户端和安全客户端:
azure-iot-provisioning-device
设备客户端:
azure-iot-device
一个传输:
azure-iot-device-amqp
、azure-iot-device-mqtt
、azure-iot-device-http
中的任一项已安装的安全客户端:
azure-iot-security-tpm
注意
此快速入门中的示例使用
azure-iot-provisioning-device-http
和azure-iot-device-mqtt
传输。
打开所选的文本编辑器。
在 registerdevice 文件夹中,创建新的 ExtractDevice.js 文件。
在 ExtractDevice.js 文件的开头添加以下
require
语句:'use strict'; var tpmSecurity = require('azure-iot-security-tpm'); var tssJs = require("tss.js"); var myTpm = new tpmSecurity.TpmSecurityClient(undefined, new tssJs.Tpm(true));
添加以下函数以实现该方法:
myTpm.getEndorsementKey(function(err, endorsementKey) { if (err) { console.log('The error returned from get key is: ' + err); } else { console.log('the endorsement key is: ' + endorsementKey.toString('base64')); myTpm.getRegistrationId((getRegistrationIdError, registrationId) => { if (getRegistrationIdError) { console.log('The error returned from get registration id is: ' + getRegistrationIdError); } else { console.log('The Registration Id is: ' + registrationId); process.exit(); } }); } });
保存并关闭 ExtractDevice.js 文件。
node ExtractDevice.js
运行该示例。
输出窗口会显示进行设备注册所需的“认可密钥”和“注册 ID” 。 复制这些值。
选择“允许访问”。 此模拟器通过端口 2321 和 2322 上的套接字进行侦听。 请勿关闭此命令窗口;本快速入门指南自始至终都需让该模拟器保持运行状态。
.\azure-iot-sdk-java\provisioning\provisioning-tools\tpm-simulator\Simulator.exe
打开第二个命令提示符。
在第二个命令提示符下导航到根文件夹,然后生成示例依赖项。
cd azure-iot-sdk-java mvn install -DskipTests=true
导航到示例文件夹。
cd provisioning/provisioning-samples/provisioning-tpm-sample
在本部分,你将生成并执行一个示例,以便从保持运行的、仍通过端口 2321 和 2322 进行侦听的 TPM 模拟器中读取认可密钥和注册 ID。 这些值用于将设备注册到设备预配服务实例。
启动 Visual Studio。
打开在 cmake 文件夹中生成的名为
azure_iot_sdks.sln
的解决方案。在 Visual Studio 菜单中,选择“生成”>“生成解决方案”以生成解决方案中的所有项目。
在 Visual Studio 的“解决方案资源管理器”窗口中,导航到 Provision_Tools 文件夹。 右键单击“tpm_device_provision”项目, 然后选择“设为启动项目”。
在 Visual Studio 菜单中,选择“调试”>“开始执行(不调试)”以运行该解决方案。 应用将读取并显示“注册 ID”和“认可密钥”。 记录或复制这些值。 在下一部分,这些值将用于设备注册。
登录到 Azure 门户,选择左侧菜单上的“所有资源”按钮,然后打开设备预配服务。 记下“ID 范围”和“预配服务全局终结点”。
编辑
src/main/java/samples/com/microsoft/azure/sdk/iot/ProvisioningTpmSample.java
,使之包括“ID 范围”和“预配服务全局终结点”,如前所述。private static final String idScope = "[Your ID scope here]"; private static final String globalEndpoint = "[Your Provisioning Service Global Endpoint here]"; private static final ProvisioningDeviceClientTransportProtocol PROVISIONING_DEVICE_CLIENT_TRANSPORT_PROTOCOL = ProvisioningDeviceClientTransportProtocol.HTTPS;
保存文件。
使用以下命令生成项目,导航到目标文件夹,然后执行创建的 .jar 文件(将
{version}
替换为 Java 版本):mvn clean install cd target java -jar ./provisioning-tpm-sample-{version}-with-deps.jar
程序开始运行后,将显示“认可密钥”和“注册 ID” 。 复制这些值,供下一部分使用。 请确保让程序保持运行。
在本部分中,你将生成并执行一个示例,该示例从你的 TPM 2.0 硬件安全模块读取认可密钥。 此值用于将设备注册到设备预配服务实例。
在命令提示符处将目录更改为 TPM 设备预配示例的项目目录。
cd '.\azure-iot-sdk-csharp\provisioning\device\samples\how to guides\TpmSample\'
键入以下命令,生成并运行 TPM 设备预配示例。 复制从 TPM 2.0 硬件安全模块返回的认可密钥,以便在以后注册设备时使用。
dotnet run -- -e
登录到 Azure 门户,并导航到设备预配服务实例。
从导航菜单的“设置”部分选择“管理注册”。
选择“单个注册”选项卡,然后选择“添加单个注册”。
在“添加注册”页的“注册 + 预配”上,提供以下信息以配置注册详细信息:
字段 说明 证明 选择“受信任的平台模块 (TPM)”作为证明机制。 受信任的平台模块 (TPM) 设置 提供将用于验证此次设备注册的认可密钥。 可以从设备的 TPM 检索认可密钥。 注册 ID 提供设备的唯一注册 ID。 可以从设备的 TPM 检索注册 ID。 预配状态 如果希望此注册用于预配其设备,请选中“启用此注册”复选框。 如果希望禁用该注册,请取消选中此框。 稍后可以更改此设置。 重新预配策略 选择一个重新预配策略,反映希望 DPS 如何处理请求重新预配的设备。 有关详细信息,请参阅重新预配策略。 选择“下一步:IoT 中心”。
在“添加注册”页的“IoT 中心”选项卡上,提供以下信息以确定注册可以预配设备的目标 IoT 中心:
字段 说明 目标 IoT 中心 选择一个或多个链接的 IoT 中心,或向 IoT 中心添加新链接。 若要详细了解如何将 IoT 中心链接到 DPS 实例,请参阅如何链接和管理 IoT 中心。 分配策略 如果选择了多个已链接的 IoT 中心,请选择要将设备分配到不同中心的方式。 如需详细了解分配策略,请参阅如何使用分配策略。
如果仅选择了一个已链接的 IoT 中心,建议使用均匀加权分发策略。选择“下一步:设备设置”
在“添加注册”页的“设备设置”选项卡上,提供以下信息以定义新预配设备的配置方式:
字段 说明 设备 ID 提供将分配给 IoT 中心中预配设备的设备 ID。 如果未提供设备 ID,将使用该注册 ID。 IoT Edge 如果预配的设备将运行 Azure IoT Edge,请选中在预配设备上启用 IoT Edge。 如果此注册适用于未启用 IoT Edge的设备,请取消选中此框。 设备标记 使用此文本框可提供要应用于预配设备的设备孪生的任何标记。 所需属性 使用此文本框可提供要应用于预配设备的设备孪生的任何所需属性。 有关详细信息,请参阅了解并在 IoT 中心内使用设备孪生。
在完成时选择“下一步:查看 + 创建”。
在“审阅 + 创建”选项卡上,验证你的全部值,然后选择“创建”。
本快速入门的 C# TPM 示例未提供注册 ID。 当系统提示为单个注册添加 ID 时,请提供自己的值。
登录到 Azure 门户,并导航到设备预配服务实例。
从导航菜单的“设置”部分选择“管理注册”。
选择“单个注册”选项卡,然后选择“添加单个注册”。
在“添加注册”页的“注册 + 预配”上,提供以下信息以配置注册详细信息:
字段 说明 证明 选择“受信任的平台模块 (TPM)”作为证明机制。 受信任的平台模块 (TPM) 设置 提供将用于验证此次设备注册的认可密钥。 可以从设备的 TPM 检索认可密钥。 注册 ID 提供设备的唯一注册 ID。 可以从设备的 TPM 检索注册 ID。 预配状态 如果希望此注册用于预配其设备,请选中“启用此注册”复选框。 如果希望禁用该注册,请取消选中此框。 稍后可以更改此设置。 重新预配策略 选择一个重新预配策略,反映希望 DPS 如何处理请求重新预配的设备。 有关详细信息,请参阅重新预配策略。 选择“下一步:IoT 中心”。
在“添加注册”页的“IoT 中心”选项卡上,提供以下信息以确定注册可以预配设备的目标 IoT 中心:
字段 说明 目标 IoT 中心 选择一个或多个链接的 IoT 中心,或向 IoT 中心添加新链接。 若要详细了解如何将 IoT 中心链接到 DPS 实例,请参阅如何链接和管理 IoT 中心。 分配策略 如果选择了多个已链接的 IoT 中心,请选择要将设备分配到不同中心的方式。 如需详细了解分配策略,请参阅如何使用分配策略。
如果仅选择了一个已链接的 IoT 中心,建议使用均匀加权分发策略。选择“下一步:设备设置”
在“添加注册”页的“设备设置”选项卡上,提供以下信息以定义新预配设备的配置方式:
字段 说明 设备 ID 提供将分配给 IoT 中心中预配设备的设备 ID。 如果未提供设备 ID,将使用该注册 ID。 IoT Edge 如果预配的设备将运行 Azure IoT Edge,请选中在预配设备上启用 IoT Edge。 如果此注册适用于未启用 IoT Edge的设备,请取消选中此框。 设备标记 使用此文本框可提供要应用于预配设备的设备孪生的任何标记。 所需属性 使用此文本框可提供要应用于预配设备的设备孪生的任何所需属性。 有关详细信息,请参阅了解并在 IoT 中心内使用设备孪生。
在完成时选择“下一步:查看 + 创建”。
在“审阅 + 创建”选项卡上,验证你的全部值,然后选择“创建”。
注册设备
在本部分,将示例代码配置为使用高级消息队列协议 (AMQP) 向设备预配服务实例发送设备的启动序列。 此启动序列使得设备可注册到与设备预配服务实例链接的 IoT 中心。
在 Azure 门户中,选择设备预配服务的“概述”选项卡。
复制“ID 范围”值。
在 Visual Studio 的“解决方案资源管理器”窗口中,导航到“Provision_Samples”文件夹。 展开名为“prov_dev_client_sample”的示例项目。 展开“源文件”,打开“prov_dev_client_sample.c”。
在该文件的顶部附近,找到每个设备协议的
#define
语句,如下所示。 确保仅取消注释SAMPLE_AMQP
。// // The protocol you wish to use should be uncommented // //#define SAMPLE_MQTT //#define SAMPLE_MQTT_OVER_WEBSOCKETS #define SAMPLE_AMQP //#define SAMPLE_AMQP_OVER_WEBSOCKETS //#define SAMPLE_HTTP
找到
id_scope
常量,将值替换为前面复制的“ID 范围”值。static const char* id_scope = "0ne00002193";
在同一文件中找到
main()
函数的定义。 确保hsm_type
变量设置为SECURE_DEVICE_TYPE_TPM
,如下所示。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”项目,然后选择“设为启动项目”。
在 Visual Studio 菜单中,选择“调试”>“开始执行(不调试)”以运行该解决方案。 出现重新生成项目的提示时,请选择“是”,以便在运行项目之前重新生成项目。
以下输出示例显示预配设备客户端示例成功启动,然后连接到设备预配服务实例来获取 IoT 中心信息并注册:
Provisioning API Version: 1.2.7 Registering... Press enter key to interrupt. Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Registration Information received from service: test-docs-hub.azure-devices.cn, deviceId: test-docs-cert-device
在 Azure 门户中,选择设备预配服务的“概述”选项卡。
复制“ID 范围”值。
在命令提示符处将目录更改为 TPM 设备预配示例的项目目录。
cd '.\azure-iot-sdk-csharp\provisioning\device\samples\how to guides\TpmSample\'
运行以下命令来注册设备。 将
<IdScope>
替换为复制的 DPS 的值,并将<RegistrationId>
替换为在创建设备注册时使用的值。dotnet run -- -s <IdScope> -r <RegistrationId>
如果设备注册成功,则会看到以下消息:
Initializing security using the local TPM... Initializing the device provisioning client... Initialized for registration Id <RegistrationId>. Registering with the device provisioning service... Registration status: Assigned. Device <RegistrationId> registered to <HubName>.azure-devices.cn. Creating TPM authentication for IoT Hub... Testing the provisioned device with IoT Hub... Sending a telemetry message... Finished.
在 Azure 门户中,选择设备预配服务的“概述”选项卡。
复制“ID 范围”值。
打开选择的文本编辑器。
在 registerdevice 文件夹中,创建新的 RegisterDevice.js 文件。
在 RegisterDevice.js 文件的开头添加以下
require
语句:'use strict'; var ProvisioningTransport = require('azure-iot-provisioning-device-http').Http; var iotHubTransport = require('azure-iot-device-mqtt').Mqtt; var Client = require('azure-iot-device').Client; var Message = require('azure-iot-device').Message; var tpmSecurity = require('azure-iot-security-tpm'); var ProvisioningDeviceClient = require('azure-iot-provisioning-device').ProvisioningDeviceClient;
注意
用于 Node.js 的 Azure IoT SDK 支持其他协议,例如 AMQP、AMQP WS、MQTT WS。 有关更多示例,请参阅 Device Provisioning Service SDK for Node.js samples(用于 Node.js 的设备预配服务 SDK 示例)。
添加 globalDeviceEndpoint 和 idScope 变量,使用它们创建 ProvisioningDeviceClient 实例。 将 {globalDeviceEndpoint} 和 {idScope} 替换为 步骤 1 中的“全局设备终结点”和“ID 范围”的值:
var provisioningHost = '{globalDeviceEndpoint}'; var idScope = '{idScope}'; var tssJs = require("tss.js"); var securityClient = new tpmSecurity.TpmSecurityClient('', new tssJs.Tpm(true)); // if using non-simulated device, replace the above line with following: //var securityClient = new tpmSecurity.TpmSecurityClient(); var provisioningClient = ProvisioningDeviceClient.create(provisioningHost, idScope, new ProvisioningTransport(), securityClient);
添加以下函数,实现设备上的方法:
provisioningClient.register(function(err, result) { if (err) { console.log("error registering device: " + err); } else { console.log('registration succeeded'); console.log('assigned hub=' + result.registrationState.assignedHub); console.log('deviceId=' + result.registrationState.deviceId); var tpmAuthenticationProvider = tpmSecurity.TpmAuthenticationProvider.fromTpmSecurityClient(result.registrationState.deviceId, result.registrationState.assignedHub, securityClient); var hubClient = Client.fromAuthenticationProvider(tpmAuthenticationProvider, iotHubTransport); var connectCallback = function (err) { if (err) { console.error('Could not connect: ' + err.message); } else { console.log('Client connected'); var message = new Message('Hello world'); hubClient.sendEvent(message, printResultFor('send')); } }; hubClient.open(connectCallback); function printResultFor(op) { return function printResult(err, res) { if (err) console.log(op + ' error: ' + err.toString()); if (res) console.log(op + ' status: ' + res.constructor.name); process.exit(1); }; } } });
保存并关闭 RegisterDevice.js 文件。
运行以下命令:
node RegisterDevice.js
请注意相关消息,这些消息模拟设备启动后连接到设备预配服务以获取 IoT 中心信息的情况。
在计算机上运行 Java 示例代码的命令窗口中按 Enter,继续运行应用程序。 请注意相关消息,这些消息模拟设备启动后连接到设备预配服务以获取 IoT 中心信息的情况。
确认设备预配注册
登录 Azure 门户。
在门户页面的左侧菜单中,选择“所有资源”。
选择设备分配到的 IoT 中心。
在“资源管理器”菜单中选择“IoT 设备” 。
如果设备预配成功,设备 ID 应显示在列表中,其状态设为“已启用”。 如果看不到设备,请选择页面顶部的“刷新”。
如果设备预配成功,设备 ID 应显示在列表中,其状态设为“已启用”。 如果看不到设备,请选择页面顶部的“刷新”。
如果设备预配成功,设备 ID 应显示在列表中,其状态设为“已启用”。 如果看不到设备,请选择页面顶部的“刷新”。
如果设备预配成功,设备 ID 应显示在列表中,其状态设为“已启用”。 如果看不到设备,请选择页面顶部的“刷新”。
注意
如果从设备的注册项中的默认值更改了“初始设备孪生状态”,则它会从中心拉取所需的孪生状态,并执行相应的操作。 有关详细信息,请参阅了解并在 IoT 中心内使用设备孪生。
清理资源
如果你打算继续使用和探索设备客户端示例,请不要清理在本快速入门中创建的资源。 如果你不打算继续学习,请按以下步骤删除本快速入门中创建的所有资源。
删除设备注册
关闭计算机上的设备客户端示例输出窗口。
在 Azure 门户的左侧菜单中,选择“所有资源”。
选择你的设备预配服务。
在“设置”菜单中,选择“管理注册” 。
选择“单个注册”选项卡。
选中在本快速入门中注册的设备的“注册 ID”旁边的复选框。
在页面顶部,选择“删除”。
从 IoT 中心删除设备注册
在 Azure 门户的左侧菜单中,选择“所有资源”。
选择 IoT 中心。
在“资源管理器”菜单中选择“IoT 设备” 。
选中在本快速入门中注册的设备的“设备 ID”旁边的复选框。
在页面顶部,选择“删除”。
后续步骤
在本快速入门中,你使用单个注册将单个设备预配到了 IoT 中心。 接下来了解如何跨多个中心预配多个设备。