资讯动态

IoT-For-Beginners 农场项目实战:在 Raspberry Pi 与虚拟 IoT 设备中使用 X.509 证书连接 Azure IoT Hub

发布时间:2026/9/14 17:47:46 来源:尧图企业网站定制
IoT-For-Beginners 农场项目实战在 Raspberry Pi 与虚拟 IoT 设备中使用 X.509 证书连接 Azure IoT Hub【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本文基于 IoT-For-Beginners 课程的“保护你的植物”Keep your plant secure一课讲解如何把土壤湿度传感器设备代码从共享密钥connection string认证切换为 X.509 证书认证。读完本文你可以完整掌握证书与私钥文件的落位方式、app.py中需要新增和替换的每一步代码主机名、设备 ID、X509实例、create_from_x509_certificate客户端创建以及如何在 Raspberry Pi 和 CounterFit 虚拟设备两种环境下验证遥测上报与直接方法Direct Method请求的收发。一、背景为什么把设备接入方式从连接字符串换成 X.509在该项目的前几课中土壤湿度传感器通过 IoT Hub 连接字符串接入云端。该连接字符串由三段以分号分隔的键值对组成详见 本课 README键示例值含义HostNamesoil-moisture-sensor.azure-devices.netIoT Hub 的 URLDeviceIdsoil-moisture-sensor设备唯一标识SharedAccessKeyBhryind...Base64设备与 IoT Hub 共同持有的对称密钥连接字符串方式本质是对称密钥认证设备首次连接时用共享密钥对“URL 过期时间戳”签名生成 SAS 令牌发送给 IoT Hub 验证。这种方式的关键缺陷是把共享密钥硬编码在代码里——一旦源码泄露任何人都可以克隆设备身份。X.509 证书方式则改用非对称加密的私钥/证书对私钥留在设备上、绝不进入源码仓库设备凭证书完成身份认证。这正是本节的改造目标。改造前的设备代码见 迁移到云端一课的 app.py其中第 7 行是connection_string connection_string第 12 行用IoTHubDeviceClient.create_from_connection_string(connection_string)创建客户端。本次改造完成后这两个位置会被证书认证逻辑取代最终形态即 code/pi 目录下的 app.py。二、前提拿到设备身份文件与证书文件X.509 接入方式所需的设备身份和证书文件由 Azure CLI 一步生成本课 README 中给出az iot hub device-identity create --device-id soil-moisture-sensor-x509 \ --am x509_thumbprint \ --output-dir . \ --hub-name hub_name该命令在 IoT Hub 中注册设备 ID 为soil-moisture-sensor-x509特意与上一课的设备区分并在当前目录生成两个文件soil-moisture-sensor-x509-key.pem—— 设备私钥绝不能提交到公共源码库soil-moisture-sensor-x509-cert.pem—— 设备的 X.509 证书。设备代码侧的第一步任务就是把这两个文件拷贝到包含设备代码的目录。文档特别提示如果你是通过 VS Code Remote SSH 在 Raspberry Pi 上开发、而密钥是在 PC 或 Mac 上生成的可以直接把文件拖进 VS Code 的资源管理器Explorer完成拷贝省去 SCP 之类的额外操作。文件放好后它们与app.py同级代码中就可以用./相对路径引用。三、修改 app.py从连接字符串切换到证书认证的完整步骤打开app.py按以下 6 步修改。每一步都对应 code/pi/soil-moisture-sensor/app.py 中的一行成品代码可直接对照。3.1 定义 IoT Hub 主机名变量在创建设备客户端之前新增主机名变量host_name host_name把host_name替换为你 IoT Hub 的主机名。获取方式打开你现有连接字符串读取其中HostName段的值——它就是你 IoT Hub 的名字形如以.azure-devices.net结尾的域名。对照仓库成品代码app.py 第 10 行写作host_name host_name.azure-devices.net3.2 定义设备 ID 变量紧接着声明设备 ID对应 app.py 第 11 行device_id soil-moisture-sensor-x509这个值必须与第 2 节az iot hub device-identity create中注册的--device-id完全一致即soil-moisture-sensor-x509。3.3 从 azure.iot.device 导入 X509 类连接使用 X.509 时需要一个持有证书文件的X509类实例。把X509加入从azure.iot.device模块导入的类列表中对应 app.py 第 5 行from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse, X509注意与改造前的 迁移到云端一课 app.py 第 5 行相比唯一的变化就是末尾多了X509。3.4 用证书与私钥文件创建 X509 实例在host_name声明下方用第 2 节生成的两个文件构造X509实例对应 app.py 第 12 行x509 X509(./soil-moisture-sensor-x509-cert.pem, ./soil-moisture-sensor-x509-key.pem)第一个参数是证书文件第二个参数是私钥文件均使用相对于app.py所在目录的路径——这就是第三节中要求“把文件拷贝到设备代码目录”的原因。3.5 用 create_from_x509_certificate 替换客户端创建逻辑找到原来用连接字符串创建device_client的那一行device_client IoTHubDeviceClient.create_from_connection_string(connection_string)将其整体替换为对应 app.py 第 14 行device_client IoTHubDeviceClient.create_from_x509_certificate(x509, host_name, device_id)从源码结构看替换后create_from_x509_certificate接收三个参数X509实例内含证书与私钥、主机名、设备 ID——三者共同替代了原来“一个连接字符串变量”的角色。之后device_client.connect()建立的就是基于 X.509 证书的双向认证连接而不是 SAS 签名连接。3.6 删除 connection_string 变量最后删除包含connection_string变量的那一行。此时设备代码中不再存在任何对称密钥SharedAccessKey彻底移出代码。四、虚拟设备CounterFit版本与 Pi 版本的差异如果你不打算上真实硬件而是用 CounterFit 在 PC 上跑虚拟设备流程完全相同但app.py的硬件抽象层不同。对比 code/virtual-device/soil-moisture-sensor/app.py 与 Pi 版本差异集中在文件头部from counterfit_connection import CounterFitConnection CounterFitConnection.init(127.0.0.1, 5000) import time from counterfit_shims_grove.adc import ADC from counterfit_shims_grove.grove_relay import GroveRelay虚拟版通过CounterFitConnection.init(127.0.0.1, 5000)连接本地 CounterFit 服务器默认 5000 端口并从counterfit_shims_grove导入ADC与GroveRelay垫片而 Pi 版直接从grove.adc/grove.grove_relay导入见 Pi 版 app.py 第 2–3 行。从第 10 行开始的 X.509 认证部分host_name、device_id、x509 实例、create_from_x509_certificate在两个版本中逐行一致因此本文第三节的修改步骤对两种环境通用。五、验证运行遥测上报与直接方法请求修改完成后运行代码。设备主循环Pi 版 app.py 第 33–40 行每 10 秒执行一轮adc.read(0)读取 Grove 模拟输入模块通道 0 上的土壤湿度传感器模拟量把读数打包为 JSON{soil_moisture: value}通过device_client.send_message(message)发送遥测time.sleep(10)休眠后进入下一轮。与此同时第 20–31 行注册了直接方法回调handle_method_request收到名为relay_on的请求时调用relay.on()Grove 继电器接在端口 5收到relay_off时调用relay.off()并以状态码 200 回复MethodResponse。验证要点与文档任务清单一致控制台先打印Connecting随后打印Connected说明设备已用 X.509 证书完成与 IoT Hub 的连接在 IoT Hub 监控或你之前的遥测查看方式中能看到持续到达的土壤湿度遥测沿用之前课练习过的方式向设备发送relay_on/relay_off直接方法请求设备日志应打印Direct method received - relay_on或relay_off继电器状态随之切换并且云端收到 200 响应。三项全部满足即表明“土壤湿度传感器程序已使用 X.509 证书接入 IoT Hub”改造完成。六、适用范围与注意事项适用设备本节针对 Raspberry Pi单板计算机与虚拟 IoT 设备两条路线。Wio TerminalArduino路线目前不可用——wio-terminal-x509.md 明确指出撰写时点的 Azure Arduino SDK 尚不支持 X.509 证书需要实验证书认证时应参考本节的 Python SDK 方案。私钥安全soil-moisture-sensor-x509-key.pem是设备身份的核心凭证与共享密钥一样不能提交到公共源码库code/pi 目录下的app.py只包含证书文件路径引用不包含密钥内容这是可以安全入库的形态。自签证书的边界本课通过az iot hub device-identity create --am x509_thumbprint生成的是自签名证书适合学习场景正式生产环境不应使用自签名证书详见 本课 README 的 X.509 章节。时间准确性无论 SAS 还是证书认证设备时钟都必须准确通常由 NTP 提供否则连接或令牌校验会失败。七、小结与进一步探索本节改造的净变化可以概括为三处导入X509并实例化指向./soil-moisture-sensor-x509-cert.pem与./soil-moisture-sensor-x509-key.pem、用create_from_x509_certificate(x509, host_name, device_id)替换create_from_connection_string(connection_string)、删除connection_string变量。设备行为10 秒周期的土壤湿度遥测、relay_on/relay_off直接方法保持不变变的是身份认证从“共享对称密钥”升级为“设备私钥 X.509 证书”从根上消除了克隆设备身份的风险。想继续深入时建议按以下路径阅读6-keep-your-plant-secure/README.md —— 加密基础、对称/非对称密钥、SAS 令牌机制与 X.509 证书原理的完整课程背景code/pi/soil-moisture-sensor/app.py 与 code/virtual-device/soil-moisture-sensor/app.py —— 本节的完整成品代码Pi 版与虚拟设备版;4-migrate-your-plant-to-the-cloud/code/pi/soil-moisture-sensor/app.py —— 改造前的连接字符串版本可用于逐行 diff 对比6-keep-your-plant-secure/assignment.md —— 本课结业作业构建一个新的 IoT 设备。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价