侧边栏壁纸
  • 累计撰写 64 篇文章
  • 累计收到 2 条评论

易语言对接阿里云IoT MQTT的签名排错笔记

2026-10-17 / 0 评论 / 5 阅读

易语言对接阿里云IoT MQTT的签名排错笔记

上周熬到快两点的时候,易语言写的MQTT客户端死活连不上阿里云IoT的实例,返回包翻来覆去只有一句“签名校验失败”。

一开始我以为是参数填错了

先是翻IoT控制台复制了三次ProductKey、DeviceName、DeviceSecret,挨个和代码里的常量比对,甚至把三个参数直接贴到官方提供的Python测试脚本里跑,居然秒连,说明密钥和设备信息本身没问题。之后我怀疑是用的第三方MQTT模块有bug,换了两个社区常用的开源模块,甚至试了手写TCP包直接发CONN请求,返回的还是签名错,坐那喝了半罐冰可乐才反应过来——问题大概率出在签名算法的实现上。

绕了半天才找到的签名坑点

阿里云IoT的MQTT签名规则不算复杂,把拼接好的待签字符串用DeviceSecret做密钥,走HmacSHA1计算后做Base64编码当password就行。我一开始图省事直接调用模块里封装好的HmacSHA1方法,算出来的结果和Python脚本输出的签名值差了好大一截。说白了就是我想当然了,没细看模块的参数说明:默认调用的时候,模块返回的是哈希结果转成的小写十六进制字符串,而阿里云要求的是对原始二进制哈希结果做Base64编码,不是对转出来的十六进制字符串编码。 中间还走了个小弯路,一开始以为是编码问题,把易语言默认的GBK文本转成UTF8再算还是不对,直到把每一步的中间结果都输出到调试框,和Python脚本的逐字节比对才找到问题。

亲测可用的签名实现步骤

我用的是精易模块的环境,其他模块逻辑是通的,记得对应改参数就行:

  1. 先拼接待签名字符串,我用的是带时间戳的一机一密模式,格式为「自定义clientId|productKey|deviceName|时间戳」,如果是免时间戳的模式记得把最后一截去掉,拼接完先转成UTF-8字节集,别直接用GBK。
  2. 调用HMAC计算方法的时候,最后一个参数一定要选返回原始字节集,不要转十六进制,我当时踩的就是这个坑。
  3. 直接对拿到的原始字节集做Base64编码,得到的就是可以直接用的MQTT连接password。

对应的代码片段如下,直接替换自己的参数就能用:

' 阿里云IoT MQTT签名计算 精易模块V10+环境
.局部变量 待签文本, 文本型
.局部变量 待签字节集, 字节集
.局部变量 密钥字节集, 字节集
.局部变量 哈希结果, 字节集
.局部变量 mqtt_pass, 文本型

待签文本 = 局_设备标识 + "|" + 局_ProductKey + "|" + 局_DeviceName + "|" + 到文本 (局_时间戳)
待签字节集 = 编码转换 (到字节集 (待签文本), #编码_GBK, #编码_UTF_8, )
密钥字节集 = 到字节集 (局_DeviceSecret)
' 最后一个参数传假,代表返回原始二进制字节集,不要转十六进制
哈希结果 = HMAC计算 (待签字节集, 密钥字节集, #算法_SHA1, 假)
mqtt_pass = _BASE64编码 (哈希结果)
额外提醒:如果用HmacSHA256签名方式,逻辑完全一致,只要把算法参数改成对应值就行;如果连不上可以先把mqtt_pass打出来,和官方签名工具生成的结果比对,不一样就是算错了。

改完这两处点运行,大概两三秒就收到了CONNACK成功的回调,熬到两点的困意瞬间消了一半。

对了,要是你换了好几个模块、对了十几次参数还是报签名错,不妨先看下HMAC方法的返回值格式,别像我似的平白绕俩小时弯路。

评论一下?

OωO
取消