LwIP环境下用SAS Token连接Azure IoT Hub的技术问题咨询
Azure IoT Hub + LwIP MQTT 连接(SAS Token 替代证书)解决方案
1. SAS Token 场景下的 altcp_tls 函数选择
不需要更换核心的 altcp_tls 框架,但要替换双向认证的配置函数:
- 之前使用的
altcp_tls_create_config_client_2wayauth是双向TLS认证逻辑(设备向服务器提供证书,同时验证服务器证书),但SAS Token属于MQTT层的身份验证机制,TLS仅需完成单向认证(设备验证服务器证书即可)。 - 改用
altcp_tls_create_config_client创建单向TLS配置,只需传入Azure IoT Hub的根CA证书(比如Baltimore CyberTrust Root),无需设备自身的证书和私钥。 - 示例代码片段:
// 加载Azure根CA证书(PEM格式) const uint8_t azure_root_ca[] = "..."; // 替换为实际CA证书内容 struct altcp_tls_config *tls_cfg = altcp_tls_create_config_client(azure_root_ca, sizeof(azure_root_ca)-1); if (!tls_cfg) { // 配置创建失败的处理逻辑 } // 将TLS配置绑定到MQTT客户端的TCP连接 mqtt_client_t *client = mqtt_client_new_with_altcp(altcp_tls_new(NULL, tls_cfg));
2. 检查TLS握手是否完成的方法
有三种可靠验证方式:
- 利用LwIP TLS会话回调监听:
通过tls_config_set_session_cb设置会话状态回调,在回调中直接判断握手结果:static void tls_session_cb(void *arg, struct altcp_tls_config *cfg, enum altcp_tls_session_status status) { if (status == ALTCP_TLS_SESSION_CONNECTED) { // TLS握手成功完成 printf("TLS handshake succeeded\n"); } else if (status == ALTCP_TLS_SESSION_FAILED) { // 握手失败,执行错误处理 printf("TLS handshake failed\n"); } } // 在创建tls_cfg后绑定回调 tls_config_set_session_cb(tls_cfg, tls_session_cb, NULL); - 结合MQTT连接回调判断:
MQTT客户端的连接回调触发并返回ERR_OK的前提是TLS握手已成功完成,因此如果mqtt_client_connect的回调返回成功,即可确认TLS握手无问题。 - 开启LwIP调试日志:
开启LWIP_ALTCP_TLS_DEBUG宏(设置为LwIP_DEBUG_LEVEL_WARNING或更高级别),通过控制台输出的日志查看TLS握手过程,出现"SSL handshake done"类标识即说明握手完成。
3. SAS Token 的正确使用方式(解决连接字符串误用问题)
不能直接将整个Azure IoT Hub连接字符串作为MQTT密码,需拆解为正确的MQTT参数:
- MQTT用户名格式:
{IoT Hub名称}.azure-devices.net/{设备ID}/?api-version=2021-04-12 - MQTT密码:单独生成的SAS Token(格式示例:
SharedAccessSignature sr={IoT Hub名称}.azure-devices.net%2Fdevices%2F{设备ID}&sig={签名}&se={过期时间戳}) - SAS Token可通过Azure官方工具生成,或基于连接字符串中的SharedAccessKey自行计算。
示例MQTT连接参数设置:
struct mqtt_connect_client_info_t ci; memset(&ci, 0, sizeof(ci)); ci.client_id = "你的设备ID"; ci.username = "你的IoT Hub名称.azure-devices.net/你的设备ID/?api-version=2021-04-12"; ci.password = "生成的SAS Token字符串"; ci.password_len = strlen(ci.password); // 发起MQTT连接 err_t err = mqtt_client_connect(client, &server_addr, MQTT_PORT, mqtt_connect_cb, NULL, &ci);
内容的提问来源于stack exchange,提问作者Yahya Aouled Amer
相关产品推荐
相关产品推荐

