【MQTT】阿里云MQTT C++ 版本 登录三元组计算获取username、password

使用了hash-library开源哈希算法库,https://conan.io/center/hash-library?tab=overview&os=Linux

全部代码:

git clone https://github.com/MisakaMikoto128/MqttSignTool.git

main.cpp

#include <iostream>
#include "aliyunmqttpasswordgenerator.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    std::string host = "iot-as-mqtt.cn-shanghai.aliyuncs.com";
    std::string productKey = "a1w78T9VVmM";
    std::string deviceName = "dev1";
    std::string deviceSecret = "1041d8898a6cdc5a851074c1543c98db";
    std::string SN = "SN";

    const AliyunMqttPasswordGenerator gen(host,productKey,deviceName,deviceSecret,SN);
    std::cout << "hostName:" << gen.hostName() << std::endl;
    std::cout << "clientId:" << gen.clientId() << std::endl;
    std::cout << "userName:" << gen.userName() << std::endl;
    std::cout << "password:" << gen.password() << std::endl;
    std::cout << "SupportSignMethod:" << gen.getSupportSignMethod()[0] << std::endl;
    return a.exec();
}

aliyunmqttpasswordgenerator.h

#ifndef ALIYUNMQTTPASSWORDGENERATOR_H
#define ALIYUNMQTTPASSWORDGENERATOR_H

#include <iostream>
#include "hash-library/sha1.h"
#include "hash-library/md5.h"
#include "hash-library/sha256.h"
#include "hash-library/hmac.h"
#include <vector>
class AliyunMqttPasswordGenerator
{
private:
    std::string host;
    std::string productKey;
    std::string deviceName;
    std::string deviceSecret;
    std::string deviceIdentifierString;

    std::string timestamp;
    std::string signContent;
    std::string signMethod = "hmacsha256";

    static const std::vector<std::string> supportSignMethod;
    int secureMode = 2;

    std::string getSignContent();
public:
    AliyunMqttPasswordGenerator(const std::string&host,const std::string&productKey,const std::string&deviceName,\
                                const std::string&deviceSecret,const std::string&deviceIdentifierString,\
                                const std::string& signMethod = "hmacsha256");

    void updateTimestamp();
    std::string clientId() const;
    std::string hostName() const;
    std::string userName() const;
    std::string password() const;
    static const std::vector<std::string> &getSupportSignMethod();
    bool signMethodIsSupported(const std::string& signMethod);
};

#endif // ALIYUNMQTTPASSWORDGENERATOR_H

aliyunmqttpasswordgenerator.cpp

#include "aliyunmqttpasswordgenerator.h"

#if defined(_WIN32) || defined(_WIN64)
//define something for Windows (64-bit only)
#include <windows.h>
#include <time.h>
static uint64_t getCurrentSecTimestamp(){
    time_t t;
    time(&t);
    return t;
}
#elif __APPLE__
#if TARGET_IPHONE_SIMULATOR
// iOS Simulator
#elif TARGET_OS_IPHONE
// iOS device
#elif TARGET_OS_MAC
// Other kinds of Mac OS
#endif
#elif __ANDROID__
// android
#elif __linux__
// linux
#include <sys/time.h>
#include <unistd.h>
static uint64_t g getCurrentSecTimestamp(){
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec;
}
#elif __unix__ // all unices not caught above
// Unix
#elif defined(_POSIX_VERSION)
// POSIX
#else
#error "Unknown"
#endif



const std::vector<std::string> AliyunMqttPasswordGenerator::supportSignMethod = {"hmacsha1","hmacmd5","hmacsha256"};

const std::vector<std::string> &AliyunMqttPasswordGenerator::getSupportSignMethod()
{
    return supportSignMethod;
}

bool AliyunMqttPasswordGenerator::signMethodIsSupported(const std::string &signMethod)
{
    bool ret = false;
    for(std::vector<std::string>::const_iterator it = this->supportSignMethod.begin(); it != this->supportSignMethod.end(); it++){
        if(*it == signMethod){
            ret = true;
        }
    }
    return ret;
}

std::string AliyunMqttPasswordGenerator::getSignContent()
{

    std::string signContent = \
            "clientId"+this->deviceIdentifierString+\
            "deviceName"+this->deviceName+ \
            "productKey"+this->productKey+ \
            "timestamp" +this->timestamp;
    return signContent;
}

AliyunMqttPasswordGenerator::AliyunMqttPasswordGenerator(const std::string&host,const std::string&productKey,const std::string&deviceName,\
                                                         const std::string&deviceSecret,const std::string&deviceIdentifierString,\
                                                         const std::string& signMethod)
{
    updateTimestamp();
    this->host = host;
    this->productKey = productKey;
    this->deviceName = deviceName;
    this->deviceSecret = deviceSecret;

    this->deviceIdentifierString = deviceIdentifierString;
    if(signMethodIsSupported(signMethod))
    {
        this->signMethod = signMethod;
    }
    //else{ //have a default value.}

    this->signContent = getSignContent();

}

void AliyunMqttPasswordGenerator::updateTimestamp()
{
    timestamp = std::to_string(getCurrentSecTimestamp());
    std::cout << "timestamp" <<getCurrentSecTimestamp()<<std::endl;
}

std::string AliyunMqttPasswordGenerator::clientId() const
{
    std::string clientId =
            this->deviceIdentifierString+ \
            "|securemode="  + std::to_string(this->secureMode) +\
            ",signmethod="  + signMethod+\
            ",timestamp="   + timestamp+"|";
    return clientId;
}

std::string AliyunMqttPasswordGenerator::hostName() const
{
    return productKey+"."+host;
}

std::string AliyunMqttPasswordGenerator::userName() const
{
    return deviceName+"&"+productKey;
}

std::string AliyunMqttPasswordGenerator::password() const
{
    std::string sha1hmac;
    if(this->signMethod == this->supportSignMethod[0])
    {
        sha1hmac = hmac<SHA1>(this->signContent, this->deviceSecret);
    }else if(this->signMethod == this->supportSignMethod[1])
    {
        sha1hmac = hmac<MD5>(this->signContent, this->deviceSecret);
    }else if(this->signMethod == this->supportSignMethod[2])
    {
        sha1hmac = hmac<SHA256>(this->signContent, this->deviceSecret);
    }
    return sha1hmac;
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设备端与阿里云IoT平台建立MQTT通道的CONNECT报文有三个关键参数:客户端标识符 (ClientId) ,用户名(User Name),密码Password)。这三个参数由设备三元组(productKey,deviceName,deviceSecret)按照阿里云IoT签名规则生成。 参数 生成方式 描述 username deviceName+"&"+productKey password sign_hmac(deviceSecret,content) sign_hmac为mqttClientId中的signmethod content为 "clientId${id}deviceName${deviceName}productKey${productKey}timestamp${timestamp}" 其中 id:表示客户端ID,64字符内。 timestamp:表示当前时间毫秒值。 clientId id+"|securemode=3,signmethod=hmacsha1,timestamp="+timestamp+"|" id:表示客户端ID,64字符内。 timestamp:表示当前时间毫秒值。 securemode:表示安全模式:可选值有2(TLS加密)和3(非加密) signmethod:表示签名算法类型。支持hmacmd5,hmacsha1和hmacsha256 2. 三元组接入示例 2.1 设备三元组信息 设备三元组 productKey = a14Xib5kdYd deviceName = light1983432 deviceSecret = oLyaKqVxtRvjH284LdhqVgVUx1UPy6zq 建立MQTT连接时参数 clientId = SN1928339 timestamp = 1539421321846 signmethod = hmacsha1 2.2 参数生成结果 mqttClientId = SN1928339|securemode=3,signmethod=hmacsha1,timestamp=1539421321846| mqttUsername = light1983432&a14Xib5kdYd mqttPassword = b2488041f64f425016b467ee1c94959ebd592ad1 生成password的content content=clientIdSN1928339deviceNamelight1983432productKeya14Xib5kdYdtimestamp1539421321846 2.3 建立连接 mqttClientId作为MQTT客户端标识符 (ClientId) mqttUsername作为MQTT用户名(User Name) mqttPassword作为MQTT密码Password) 在线Password生成算法验证
在使用 Micropython 连接阿里云 MQTT 时,需要计算三元组信息以获取 MQTT 连接参数。三元组包括:设备的 ProductKey、DeviceName 和 DeviceSecret。 下面是计算 MQTT 连接参数的步骤: 1. 首先需要在阿里云 IoT 平台创建一个产品,获取 ProductKey。 2. 在该产品下创建一个设备,获取 DeviceName。 3. 生成 DeviceSecret,可以在设备详情页中进行查看或重新生成。 4. 计算 MQTT 连接参数。 首先需要将 ProductKey、DeviceName 和当前时间(精确到秒)按照以下格式拼接成一个字符串: ``` clientId = "p<productKey>.<deviceName>|timestamp=123456789" ``` 其中,`<productKey>` 为阿里云 IoT 平台中创建的产品的 ProductKey,`<deviceName>` 为该产品下创建的设备的 DeviceName,`123456789` 为当前时间戳。 然后,将 DeviceSecret 和上述字符串进行 HMAC-SHA1 加密,得到一个 20 字节的二进制字符串。 最后,将上述二进制字符串转换为 Base64 编码的字符串,即为设备的 password。 ``` import time import hashlib import hmac import base64 # 三元组信息 productKey = "your_productKey" deviceName = "your_deviceName" deviceSecret = "your_deviceSecret" # 计算时间戳 timestamp = str(int(time.time())) # 组装 clientId clientId = "p{}.{}|timestamp={}".format(productKey, deviceName, timestamp) # 计算 password content = clientId.encode("utf-8") secret = deviceSecret.encode("utf-8") signature = hmac.new(secret, content, hashlib.sha1).digest() password = base64.b64encode(signature).decode("utf-8") print("clientId:", clientId) print("password:", password) ``` 运行上述代码即可得到 clientId 和 password,用于连接阿里云 MQTT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值