
IoT 农场安全实战基于 X.509 证书与无服务器代码构建安全 IoT 设备的完整指南【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners导读本文以「IoT-For-Beginners」开源课程中 6-keep-your-plant-secure 一课为核心围绕数字农业项目的收尾环节——IoT 设备安全展开从对称密钥与 X.509 证书两种加密方案的原理对比到使用 Azure CLI 生成自签名 X.509 证书、改造设备代码完成安全连接再到通过无服务器代码Azure Functions由遥测事件驱动执行器控制。读完后你将能独立完成传感器采集 → IoT Hub 安全连接 → 无服务器函数触发执行器这一完整安全链路并掌握这一课结课作业assignment中构建新 IoT 设备的评分要点与实现路径。为什么必须保护 IoT 设备前 5 课你已经构建了一个土壤监测设备并将其接入云端设备持续发送土壤湿度遥测数据云端依据数据下发指令自动浇水。但如果竞争对手雇用的黑客夺取了你 IoT 设备的控制权会怎样他们可以持续上报土壤湿度很高让灌溉系统永远不启动、植物缺水枯死也可以让浇水系统一直运行把植物淹死并造成巨额水费。因此IoT 安全的本质是双向认证只允许预期的设备向云端 IoT 服务发送遥测数据也只允许你的云服务向设备下发命令。IoT 数据本身还可能是私密的如医疗或私人数据整个应用都必须考虑安全性以防数据泄露。从这一课的原文可以看到不安全的 IoT 应用面临一系列真实风险伪造设备发送错误数据导致应用错误响应例如持续的高湿度读数使灌溉永不开启未授权用户读取 IoT 数据包括个人或企业关键数据黑客向设备发送命令对设备或所连接的硬件造成破坏通过入侵 IoT 设备横向进入内部网络访问私有系统恶意用户窃取个人数据用于敲诈勒索。这些并非假设性场景行业中有大量真实案例2018 年黑客通过养鱼缸温控器上开放的 WiFi 接入点入侵赌场网络窃取数据2016 年 Mirai 僵尸网络利用默认用户名/密码的 DVR、摄像头等设备发起大规模 DDoS 攻击CloudPets 联网玩具的用户数据库曾公开暴露在互联网上健身应用 Strava 的路线标签功能间接暴露了用户住址。 安全是一个宏大的话题这一课只涉及设备连接云端的一些基础内容。传输中的数据变化监测、直接入侵设备、设备配置篡改等主题不在本课范围内。业界甚至出现了类似设备杀毒软件的专用工具如 Azure Defender for IoT专门针对小型、低功耗的 IoT 设备设计。密码学基础从替换密码到现代加密设备连接到 IoT 服务时用 ID 标识自己但 ID 可以被克隆——黑客可以设置一台使用相同 ID 但发送伪造数据的恶意设备。解决办法是把发送的数据转换为乱码格式使用只有设备和云端知道的某种值来打乱数据。这个过程称为加密encryption用于加密数据的值称为加密密钥encryption key云端用解密decryption把数据还原为可读格式使用相同密钥或解密密钥。如果加密消息无法被密钥解密说明设备已被入侵消息被拒绝。这一套加密/解密技术统称为密码学cryptography。早期密码学最早的密码学类型是替换密码可追溯到约 3500 年前用一个字母替换另一个字母。例如凯撒密码Caesar cipher将字母表按固定位数平移只有发信人和收信人知道平移位数维吉尼亚密码Vigenère cipher更进一步用单词加密文本使原文中每个字母被平移不同的位数。历史上密码学被广泛使用美索不达米亚保护陶工釉料配方、印度书写秘密情书、古埃及保密魔法咒语。现代密码学现代密码学远比早期方法先进使用复杂的数学对数据进行加密密钥空间大到使暴力破解几乎不可能。现代生活中加密无处不在浏览网页时地址栏的HTTPS超文本传输协议安全版意味着浏览器与服务器之间的通信被加密电脑硬盘也可以全盘加密即使设备被盗没有密码也读不出任何数据。当然并非一切都安全有些设备完全没有安全措施有些使用容易被破解的密钥甚至同型号设备共用同一个密钥——许多高度私密的 IoT 设备在 WiFi/蓝牙连接上使用相同的出厂密码你能连自己的设备就能连别人的。 尽管现代密码学宣称破解加密需要数十亿年但量子计算的兴起使得在极短时间内破解所有已知加密成为可能对称加密与非对称加密加密分为两类对称加密Symmetric加密和解密使用同一个密钥发送方和接收方都必须知道该密钥。这是安全性最低的类型因为密钥必须以某种方式共享——发送方要先给接收方传递密钥。如果密钥在传输中被窃取或发送方/接收方被入侵而密钥被发现加密即被破解。非对称加密Asymmetric使用两个密钥——加密密钥与解密密钥即公钥/私钥对。公钥用于加密消息但无法解密私钥用于解密消息但无法加密。接收方共享公钥发送方用公钥加密后发送接收方用自己的私钥解密。非对称加密更安全因为私钥由接收方私藏、永不共享公钥可以给任何人因为它只能用于加密。对称加密更快非对称加密更安全。一些系统两者并用先用非对称加密传输并共享对称密钥再用对称密钥加密全部数据——既让对称密钥的共享更安全又保留了加密解密的高速度。保护 IoT 设备的两种方式IoT 设备可以用对称加密或非对称加密来保护对称更容易但安全性较低。对称密钥与连接字符串当你将 IoT 设备接入 IoT Hub 时使用的是连接字符串例如HostNamesoil-moisture-sensor.azure-devices.net;DeviceIdsoil-moisture-sensor;SharedAccessKeyBhryind7kKEIDxubK61RiEHHRTrPl7HUow8cEm/mU0该连接字符串由分号分隔的三个部分构成每个部分都是键值键值说明HostNamesoil-moisture-sensor.azure-devices.netIoT Hub 的 URLDeviceIdsoil-moisture-sensor设备的唯一 IDSharedAccessKeyBhryind7kKEIDxubK61RiEHHRTrPl7HUow8cEm/mU0设备与 IoT Hub 共知的对称密钥最后一部分SharedAccessKey就是设备与 IoT Hub 双方共知的对称密钥。这个密钥永远不会从设备发送到云端也不会从云端发送到设备它只用于加密发送/接收的数据。连接时的认证流程设备首次尝试连接时会发送一个共享访问签名SAS令牌包含IoT Hub 的 URL、签名过期时间戳通常为当前时间起 1 天、以及签名——签名是用连接字符串中的共享访问密钥对 URL 与过期时间加密得到的。IoT Hub 用共享访问密钥解密该签名若解密结果与 URL 和过期时间匹配则允许设备连接同时验证当前时间早于过期时间防止恶意设备捕获真实设备的 SAS 令牌后重放。这是一种精巧的证明发送方是正确的设备的方式同时发送已知数据的明文与密文服务器解密密文后与明文比对一致则说明双方持有相同的对称密钥。 由于存在过期时间IoT 设备必须知道准确时间通常从 NTP 模块负责 NTP 校时。连接建立后设备与 IoT Hub 之间双向传输的所有数据都用共享访问密钥加密。安全实践要点把密钥写在代码里是糟糕的做法——黑客拿到源码就拿到了密钥发布代码时还需为每台设备重新编译。更好的做法是从硬件安全模块设备上的加密值存储芯片加载密钥。学习阶段为了方便通常把密钥写进代码如前几课所做但绝不要把密钥提交到公开的源码仓库。每台设备有 2 个密钥和 2 条对应的连接字符串这允许密钥轮换若第一个密钥被泄露可以切换到另一个密钥并重新生成被泄露的那个。✅ 可以做个实验修改连接字符串中的SharedAccessKey部分再连接设备观察会发生什么也可以思考如果多台设备共享同一条连接字符串会怎样X.509 证书与公钥基础设施使用公钥/私钥对进行非对称加密时需要把公钥提供给想给你发数据的人。问题是接收方如何确信这确实是你的公钥而不是有人冒充你解决办法是把公钥放进一个由可信第三方验证过的证书里这就是X.509 证书。X.509 证书是包含公钥/私钥对中公钥部分的数字文档通常由被称为证书颁发机构CA的可信组织签发并由 CA 进行数字签名以表明该密钥有效且属于你。你信任证书、信任公钥确实属于证书中所声明的人是因为你信任 CA——就像你信任护照或驾照是因为信任签发国。证书需要花钱因此测试用途下也可以自签名自己创建并自己签名的证书。 生产环境发布绝不应使用自签名证书。证书中包含多个字段公钥归属者、签发该证书的 CA 详情、有效期限、以及公钥本身。使用证书前良好的实践是验证它确实由原始 CA 签发。使用 X.509 证书时发送方与接收方各自拥有自己的公钥/私钥对并持有包含各自公钥的 X.509 证书双方交换证书用对方的公钥加密发送的数据用自己的私钥解密接收的数据。X.509 证书的一大优势是可以在设备间共享你可以创建一个证书上传到 IoT Hub供所有设备使用每台设备只需知道私钥来解密从 IoT Hub 收到的消息。设备用于加密发往 IoT Hub 消息的证书由微软发布与许多 Azure 服务使用的证书相同有时会内置于 SDK 中——公钥本来就是公开的Azure 公钥只能用于加密发往 Azure 的数据、不能解密因此可以放在任何地方包括源码例如可见于 Azure IoT C SDK 的certs/certs.c源码中。动手生成并使用 X.509 证书生成 X.509 证书的步骤是创建公钥/私钥对。最广泛使用的算法之一是RSARivest–Shamir–Adleman。将公钥连同关联数据提交签名——由 CA 签名或自签名。Azure CLI 提供了在 IoT Hub 中创建新设备身份并自动生成公钥/私钥对与自签名证书的命令。 如果想看不用 Azure CLI 的详细步骤可参考 Microsoft IoT Hub 文档中的《Using OpenSSL to create self-signed certificates》教程。任务一用 X.509 证书创建设备身份运行以下命令注册新的设备身份自动生成密钥和证书az iot hub device-identity create --device-id soil-moisture-sensor-x509 \ --am x509_thumbprint \ --output-dir . \ --hub-name hub_name将hub_name替换为你实际使用的 IoT Hub 名称。该命令会创建一个 ID 为soil-moisture-sensor-x509的设备与上一课创建的设备身份区分开并在当前目录生成 2 个文件soil-moisture-sensor-x509-key.pem— 设备的私钥文件soil-moisture-sensor-x509-cert.pem— 设备的 X.509 证书文件。务必妥善保管这些文件私钥文件不应被提交到公开源码仓库。任务二在设备代码中使用 X.509 证书根据你的硬件选择对应的指南完成连接改造Arduino / Wio Terminalwio-terminal-x509.md单板计算机 / Raspberry Pi / 虚拟 IoT 设备single-board-computer-x509.md注意截至课程编写时Azure Arduino SDK 尚不支持 X.509 证书。若想用 Wio Terminal 实验 X.509可参照 虚拟 IoT 设备的 Python SDK 说明。连接 IoT Hub 的改造步骤Python / Raspberry Pi / 虚拟设备以本仓库代码为证virtual-device/soil-moisture-sensor/app.py 与 pi/soil-moisture-sensor/app.py 展示了完整的 X.509 连接写法复制文件把.pem密钥与证书文件复制到设备代码所在文件夹Raspberry Pi 通过 VS Code Remote SSH 时可直接拖拽。声明主机名在创建设备客户端之前添加变量host_name host_namehost_name为 IoT Hub 的主机名取自连接字符串的HostName部分即 IoT Hub 名称加上.azure-devices.net后缀。声明设备 IDdevice_id soil-moisture-sensor-x509导入 X509 类在从azure.iot.device模块的导入列表中加上X509from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse, X509创建 X509 实例在host_name声明下方加入x509 X509(./soil-moisture-sensor-x509-cert.pem, ./soil-moisture-sensor-x509-key.pem)替换客户端创建方式把原来基于连接字符串的device_client创建代码替换为device_client IoTHubDeviceClient.create_from_x509_certificate(x509, host_name, device_id)删除connection_string变量。运行验证运行代码监控发往 IoT Hub 的消息并照常发送直接方法direct method请求——你将看到设备成功连接、发送土壤湿度读数并能接收直接方法请求。仓库中的示例代码还展示了 X.509 连接与直接方法处理如何协同工作设备用GroveRelay(5)创建继电器执行器虚拟设备中通过counterfit_shims_grove仿真handle_method_request根据relay_on/relay_off方法名开关继电器并通过MethodResponse.create_from_method_request返回 200 状态主循环每 10 秒读取一次 ADC 上的土壤湿度并作为 JSON 遥测消息发送while True: soil_moisture adc.read(0) print(Soil moisture:, soil_moisture) message Message(json.dumps({ soil_moisture: soil_moisture })) device_client.send_message(message) time.sleep(10)用无服务器代码驱动执行器Azure Function 实现遥测触发控制课程作业要求通过无服务器代码控制执行器这正是本课安全链路的落点设备安全连接后遥测事件进入 IoT Hub由 5-migrate-application-to-the-cloud 一课实现的 Azure Function 消费并下发直接方法命令。从 iot-hub-trigger/init.py 可以看到完整逻辑def main(event: func.EventHubEvent): body json.loads(event.get_body().decode(utf-8)) device_id event.iothub_metadata[connection-device-id] soil_moisture body[soil_moisture] if soil_moisture 450: direct_method CloudToDeviceMethod(method_namerelay_on, payload{}) else: direct_method CloudToDeviceMethod(method_namerelay_off, payload{}) registry_manager_connection_string os.environ[REGISTRY_MANAGER_CONNECTION_STRING] registry_manager IoTHubRegistryManager(registry_manager_connection_string) registry_manager.invoke_device_method(device_id, direct_method)其对应绑定配置 function.json 使用eventHubTrigger类型connection指向IOT_HUB_CONNECTION_STRING消费组为$Default数据类型为 binary——正是这一课中设备遥测 → 云端逻辑 → 设备执行器闭环的云端一侧。关键实现要点阈值判断soil_moisture 450时下发relay_on否则下发relay_off与设备端handle_method_request中的方法名一一对应连接串从环境变量REGISTRY_MANAGER_CONNECTION_STRING读取避免把密钥写死在代码里使用IoTHubRegistryManager.invoke_device_method()向设备发送云到设备直接方法。当设备端采用 X.509 证书连接时由于认证发生在设备 ↔ IoT Hub 之间无服务器函数一侧无需感知 X.509 细节——这正体现了设备安全连接 云端安全命令下发的分层安全模型。结课作业构建一个全新的安全 IoT 设备本课是该项目的最后一课配套作业assignment.md要求你综合运用 6 节课所学完成一个端到端项目。作业要求在过去 6 节课中你学习了数字农业以及如何用 IoT 设备采集数据来预测植物生长、依据土壤湿度读数自动浇水。现在请运用所学用你选择的传感器和执行器构建一个新 IoT 设备向 IoT Hub 发送遥测数据并通过无服务器代码用这些数据控制执行器。你可以使用本项目或此前项目中用过的传感器与执行器如果手头有别的硬件也可以尝试新东西。评分标准Rubric标准优秀合格待改进编写使用传感器和执行器的 IoT 设备代码设备代码同时驱动传感器与执行器正常工作设备代码只驱动传感器或只驱动执行器无法编写使用传感器或执行器的设备代码将 IoT 设备连接到 IoT Hub成功部署 IoT Hub向其发送遥测并从中接收命令成功部署 IoT Hub但只能发送遥测或只能接收命令无法部署 IoT Hub 或无法与其通信用无服务器代码控制执行器成功部署由遥测事件触发的 Azure Function 来控制设备成功部署由遥测事件触发的 Azure Function但无法控制执行器无法部署 Azure Function对照评分表自查优秀档需要同时满足三点——传感器执行器双端齐备的固件/代码、IoT Hub 双向通信遥测上行 命令下行、以及遥测事件驱动的 Azure Function 成功操控执行器。你可以复用本课 code/virtual-device 与 code/pi 中ADC 传感器 继电器执行器 直接方法的模式将传感器读数换成你选择的传感器把relay_on/relay_off换成对应执行器的控制方法并在 Azure Function 中替换阈值判断与直接方法名。挑战与延伸 挑战用 Azure Portal 管理云资源创建、管理和删除 Azure 服务如资源组、IoT Hub有多种方式其中一种是 Azure Portal——基于 Web 的 GUI 界面。尝试用 Portal 创建一个 IoT Hub然后删除它。提示通过 Portal 创建服务时不需要预先创建资源组可以在创建服务的过程中一并创建。用完后务必删除清理云资源本课是该项目最后一课完成课程与作业后不要忘记清理云服务资源以降低潜在费用。注意作业需要使用这些服务因此请先完成作业再清理。清理步骤可参考仓库根目录的 clean-up.md 指南。复习与自学建议在维基百科阅读密码学历史在维基百科阅读 X.509 证书的详细介绍。小结本课完成了数字农业项目从能跑到安全的进阶你掌握了对称密钥与 X.509 证书两种设备认证方案及其原理SAS 令牌认证流程、公钥/私钥对、CA 签发机制并用 Azure CLI 实际生成了自签名 X.509 证书、改造了 Python 设备代码完成安全连接随后通过 Azure Function 直接方法实现了遥测驱动执行器的无服务器闭环。最终的结课作业要求你把传感器、执行器、IoT Hub 与无服务器代码组合成一个全新的安全设备——这正是对 6 节课所学全部能力的综合检验。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考