• qt小例子:实现阿里云物联网设备登录信息计算器


    阿里云的物联网平台设备端使用mqtt时必须要使用阿里云加密算法通过设备三元组算出来的username、password、clientId才可以连接成功

    使用mqtt.fx、mqttBox等客户端软件时必须要根据设备三元组计算出正确的登录信息,最近在使用qt,所以使用qt写了这么一个小工具

    做出来的基本效果为:

    在下面输入阿里云物联网平台设备的三元组信息,即可生成对应得mqtt用户名密码和ID信息。

    使用的阿里云加密算法代码为:

      1 #include"hmac.h"
      2 #include <stdio.h>
      3 #include <stdint.h>
      4 #include <string.h>
      5 #define PRODUCTKEY_MAXLEN (20)
      6 #define DEVICENAME_MAXLEN (32)
      7 #define DEVICESECRET_MAXLEN (64)
      8 
      9 #define SIGN_SOURCE_MAXLEN (200)
     10 #define CLIENTID_MAXLEN (150)
     11 #define USERNAME_MAXLEN (64)
     12 #define PASSWORD_MAXLEN (65)
     13 
     14 /******************************
     15  * hmac-sha256 implement below
     16  ******************************/
     17 #define SHA256_KEY_IOPAD_SIZE (64)
     18 #define SHA256_DIGEST_SIZE (32)
     19 
     20 static void utils_hmac_sha256(const uint8_t *msg, uint32_t msg_len, const uint8_t *key, uint32_t key_len, uint8_t output[32]);
     21 
     22 static const uint32_t K[] = {
     23     0x428A2F98,
     24     0x71374491,
     25     0xB5C0FBCF,
     26     0xE9B5DBA5,
     27     0x3956C25B,
     28     0x59F111F1,
     29     0x923F82A4,
     30     0xAB1C5ED5,
     31     0xD807AA98,
     32     0x12835B01,
     33     0x243185BE,
     34     0x550C7DC3,
     35     0x72BE5D74,
     36     0x80DEB1FE,
     37     0x9BDC06A7,
     38     0xC19BF174,
     39     0xE49B69C1,
     40     0xEFBE4786,
     41     0x0FC19DC6,
     42     0x240CA1CC,
     43     0x2DE92C6F,
     44     0x4A7484AA,
     45     0x5CB0A9DC,
     46     0x76F988DA,
     47     0x983E5152,
     48     0xA831C66D,
     49     0xB00327C8,
     50     0xBF597FC7,
     51     0xC6E00BF3,
     52     0xD5A79147,
     53     0x06CA6351,
     54     0x14292967,
     55     0x27B70A85,
     56     0x2E1B2138,
     57     0x4D2C6DFC,
     58     0x53380D13,
     59     0x650A7354,
     60     0x766A0ABB,
     61     0x81C2C92E,
     62     0x92722C85,
     63     0xA2BFE8A1,
     64     0xA81A664B,
     65     0xC24B8B70,
     66     0xC76C51A3,
     67     0xD192E819,
     68     0xD6990624,
     69     0xF40E3585,
     70     0x106AA070,
     71     0x19A4C116,
     72     0x1E376C08,
     73     0x2748774C,
     74     0x34B0BCB5,
     75     0x391C0CB3,
     76     0x4ED8AA4A,
     77     0x5B9CCA4F,
     78     0x682E6FF3,
     79     0x748F82EE,
     80     0x78A5636F,
     81     0x84C87814,
     82     0x8CC70208,
     83     0x90BEFFFA,
     84     0xA4506CEB,
     85     0xBEF9A3F7,
     86     0xC67178F2,
     87 };
     88 
     89 #define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
     90 #define ROTR(x, n) (SHR(x, n) | (x << (32 - n)))
     91 
     92 #define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
     93 #define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
     94 
     95 #define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
     96 #define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
     97 
     98 #define F0(x, y, z) ((x & y) | (z & (x | y)))
     99 #define F1(x, y, z) (z ^ (x & (y ^ z)))
    100 
    101 #define R(t)                             
    102     (                                    
    103         W[t] = S1(W[t - 2]) + W[t - 7] + 
    104                S0(W[t - 15]) + W[t - 16])
    105 
    106 #define P(a, b, c, d, e, f, g, h, x, K)          
    107     {                                            
    108         temp1 = h + S3(e) + F1(e, f, g) + K + x; 
    109         temp2 = S2(a) + F0(a, b, c);             
    110         d += temp1;                              
    111         h = temp1 + temp2;                       
    112     }
    113 /**
    114  * rief          SHA-256 context structure
    115  */
    116 typedef struct
    117 {
    118     uint32_t total[2];        /*!< number of bytes processed  */
    119     uint32_t state[8];        /*!< intermediate digest state  */
    120     unsigned char buffer[64]; /*!< data block being processed */
    121     int is224;                /*!< 0 => SHA-256, else SHA-224 */
    122 } iot_sha256_context;
    123 
    124 #ifndef PUT_UINT32_BE
    125 #define PUT_UINT32_BE(n, b, i)                     
    126     do                                             
    127     {                                              
    128         (b)[(i)] = (unsigned char)((n) >> 24);     
    129         (b)[(i) + 1] = (unsigned char)((n) >> 16); 
    130         (b)[(i) + 2] = (unsigned char)((n) >> 8);  
    131         (b)[(i) + 3] = (unsigned char)((n));       
    132     } while (0)
    133 #endif
    134 
    135 /*
    136  * 32-bit integer manipulation macros (big endian)
    137  */
    138 #ifndef GET_UINT32_BE
    139 #define GET_UINT32_BE(n, b, i)                                                                                                        
    140     do                                                                                                                                
    141     {                                                                                                                                 
    142         (n) = ((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | ((uint32_t)(b)[(i) + 2] << 8) | ((uint32_t)(b)[(i) + 3]); 
    143     } while (0)
    144 #endif
    145 static const unsigned char sha256_padding[64] = {
    146     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    147     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    148     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    149     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    150 
    151 void utils_sha256_process(iot_sha256_context *ctx, const unsigned char data[64])
    152 {
    153     uint32_t temp1, temp2, W[64];
    154     uint32_t A[8];
    155     unsigned int i;
    156 
    157     for (i = 0; i < 8; i++)
    158     {
    159         A[i] = ctx->state[i];
    160     }
    161 
    162     for (i = 0; i < 64; i++)
    163     {
    164         if (i < 16)
    165         {
    166             GET_UINT32_BE(W[i], data, 4 * i);
    167         }
    168         else
    169         {
    170             R(i);
    171         }
    172 
    173         P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i]);
    174 
    175         temp1 = A[7];
    176         A[7] = A[6];
    177         A[6] = A[5];
    178         A[5] = A[4];
    179         A[4] = A[3];
    180         A[3] = A[2];
    181         A[2] = A[1];
    182         A[1] = A[0];
    183         A[0] = temp1;
    184     }
    185 
    186     for (i = 0; i < 8; i++)
    187     {
    188         ctx->state[i] += A[i];
    189     }
    190 }
    191 void utils_sha256_init(iot_sha256_context *ctx)
    192 {
    193     memset(ctx, 0, sizeof(iot_sha256_context));
    194 }
    195 
    196 void utils_sha256_starts(iot_sha256_context *ctx)
    197 {
    198     int is224 = 0;
    199     ctx->total[0] = 0;
    200     ctx->total[1] = 0;
    201 
    202     if (is224 == 0)
    203     {
    204         /* SHA-256 */
    205         ctx->state[0] = 0x6A09E667;
    206         ctx->state[1] = 0xBB67AE85;
    207         ctx->state[2] = 0x3C6EF372;
    208         ctx->state[3] = 0xA54FF53A;
    209         ctx->state[4] = 0x510E527F;
    210         ctx->state[5] = 0x9B05688C;
    211         ctx->state[6] = 0x1F83D9AB;
    212         ctx->state[7] = 0x5BE0CD19;
    213     }
    214 
    215     ctx->is224 = is224;
    216 }
    217 void utils_sha256_update(iot_sha256_context *ctx, const unsigned char *input, uint32_t ilen)
    218 {
    219     size_t fill;
    220     uint32_t left;
    221 
    222     if (ilen == 0)
    223     {
    224         return;
    225     }
    226 
    227     left = ctx->total[0] & 0x3F;
    228     fill = 64 - left;
    229 
    230     ctx->total[0] += (uint32_t)ilen;
    231     ctx->total[0] &= 0xFFFFFFFF;
    232 
    233     if (ctx->total[0] < (uint32_t)ilen)
    234     {
    235         ctx->total[1]++;
    236     }
    237 
    238     if (left && ilen >= fill)
    239     {
    240         memcpy((void *)(ctx->buffer + left), input, fill);
    241         utils_sha256_process(ctx, ctx->buffer);
    242         input += fill;
    243         ilen -= fill;
    244         left = 0;
    245     }
    246 
    247     while (ilen >= 64)
    248     {
    249         utils_sha256_process(ctx, input);
    250         input += 64;
    251         ilen -= 64;
    252     }
    253 
    254     if (ilen > 0)
    255     {
    256         memcpy((void *)(ctx->buffer + left), input, ilen);
    257     }
    258 }
    259 
    260 void utils_sha256_finish(iot_sha256_context *ctx, uint8_t output[32])
    261 {
    262     uint32_t last, padn;
    263     uint32_t high, low;
    264     unsigned char msglen[8];
    265 
    266     high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
    267     low = (ctx->total[0] << 3);
    268 
    269     PUT_UINT32_BE(high, msglen, 0);
    270     PUT_UINT32_BE(low, msglen, 4);
    271 
    272     last = ctx->total[0] & 0x3F;
    273     padn = (last < 56) ? (56 - last) : (120 - last);
    274 
    275     utils_sha256_update(ctx, sha256_padding, padn);
    276     utils_sha256_update(ctx, msglen, 8);
    277 
    278     PUT_UINT32_BE(ctx->state[0], output, 0);
    279     PUT_UINT32_BE(ctx->state[1], output, 4);
    280     PUT_UINT32_BE(ctx->state[2], output, 8);
    281     PUT_UINT32_BE(ctx->state[3], output, 12);
    282     PUT_UINT32_BE(ctx->state[4], output, 16);
    283     PUT_UINT32_BE(ctx->state[5], output, 20);
    284     PUT_UINT32_BE(ctx->state[6], output, 24);
    285 
    286     if (ctx->is224 == 0)
    287     {
    288         PUT_UINT32_BE(ctx->state[7], output, 28);
    289     }
    290 }
    291 
    292 static void _hex2str(uint8_t *input, uint16_t input_len, char *output)
    293 {
    294     char *zEncode = "0123456789ABCDEF";
    295     int i = 0, j = 0;
    296 
    297     for (i = 0; i < input_len; i++)
    298     {
    299         output[j++] = zEncode[(input[i] >> 4) & 0xf];
    300         output[j++] = zEncode[(input[i]) & 0xf];
    301     }
    302 }
    303 
    304 static void utils_hmac_sha256(const uint8_t *msg, uint32_t msg_len, const uint8_t *key, uint32_t key_len, uint8_t output[32])
    305 {
    306     iot_sha256_context context;
    307     uint8_t k_ipad[SHA256_KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad  */
    308     uint8_t k_opad[SHA256_KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
    309     int32_t i;
    310 
    311     if ((NULL == msg) || (NULL == key) || (NULL == output))
    312     {
    313         return;
    314     }
    315 
    316     if (key_len > SHA256_KEY_IOPAD_SIZE)
    317     {
    318         return;
    319     }
    320 
    321     /* start out by storing key in pads */
    322     memset(k_ipad, 0, sizeof(k_ipad));
    323     memset(k_opad, 0, sizeof(k_opad));
    324     memcpy(k_ipad, key, key_len);
    325     memcpy(k_opad, key, key_len);
    326 
    327     /* XOR key with ipad and opad values */
    328     for (i = 0; i < SHA256_KEY_IOPAD_SIZE; i++)
    329     {
    330         k_ipad[i] ^= 0x36;
    331         k_opad[i] ^= 0x5c;
    332     }
    333 
    334     /* perform inner SHA */
    335     utils_sha256_init(&context);                                  /* init context for 1st pass */
    336     utils_sha256_starts(&context);                                /* setup context for 1st pass */
    337     utils_sha256_update(&context, k_ipad, SHA256_KEY_IOPAD_SIZE); /* start with inner pad */
    338     utils_sha256_update(&context, msg, msg_len);                  /* then text of datagram */
    339     utils_sha256_finish(&context, output);                        /* finish up 1st pass */
    340 
    341     /* perform outer SHA */
    342     utils_sha256_init(&context);                                  /* init context for 2nd pass */
    343     utils_sha256_starts(&context);                                /* setup context for 2nd pass */
    344     utils_sha256_update(&context, k_opad, SHA256_KEY_IOPAD_SIZE); /* start with outer pad */
    345     utils_sha256_update(&context, output, SHA256_DIGEST_SIZE);    /* then results of 1st hash */
    346     utils_sha256_finish(&context, output);                        /* finish up 2nd pass */
    347 }
    348 
    349 #define TIMESTAMP_VALUE "2524608000000"
    350 #define MQTT_CLINETID_KV "|timestamp=2524608000000,_v=paho-c-1.0.0,securemode=3,signmethod=hmacsha256,lan=C|"
    351 
    352 int aiotMqttSign(const char *productKey, const char *deviceName, const char *deviceSecret,
    353                  char clientId[150], char username[64], char password[65])
    354 {
    355     char deviceId[PRODUCTKEY_MAXLEN + DEVICENAME_MAXLEN + 2] = {0};
    356     char macSrc[SIGN_SOURCE_MAXLEN] = {0};
    357     uint8_t macRes[32] = {0};
    358     int res;
    359 
    360     /* check parameters */
    361     if (productKey == NULL || deviceName == NULL || deviceSecret == NULL ||
    362         clientId == NULL || username == NULL || password == NULL)
    363     {
    364         return -1;
    365     }
    366     if ((strlen(productKey) > PRODUCTKEY_MAXLEN) || (strlen(deviceName) > DEVICENAME_MAXLEN) ||
    367         (strlen(deviceSecret) > DEVICESECRET_MAXLEN))
    368     {
    369         return -1;
    370     }
    371 
    372     /* setup deviceId */
    373     memcpy(deviceId, deviceName, strlen(deviceName));
    374     memcpy(deviceId + strlen(deviceId), "&", strlen("&"));
    375     memcpy(deviceId + strlen(deviceId), productKey, strlen(productKey));
    376 
    377     /* setup clientid */
    378     memcpy(clientId, deviceId, strlen(deviceId));
    379     memcpy(clientId + strlen(deviceId), MQTT_CLINETID_KV, strlen(MQTT_CLINETID_KV));
    380     memset(clientId + strlen(deviceId) + strlen(MQTT_CLINETID_KV), 0, 1);
    381 
    382     /* setup username */
    383     memcpy(username, deviceId, strlen(deviceId));
    384     memset(username + strlen(deviceId), 0, 1);
    385 
    386     /* setup password */
    387     memcpy(macSrc, "clientId", strlen("clientId"));
    388     memcpy(macSrc + strlen(macSrc), deviceId, strlen(deviceId));
    389     memcpy(macSrc + strlen(macSrc), "deviceName", strlen("deviceName"));
    390     memcpy(macSrc + strlen(macSrc), deviceName, strlen(deviceName));
    391     memcpy(macSrc + strlen(macSrc), "productKey", strlen("productKey"));
    392     memcpy(macSrc + strlen(macSrc), productKey, strlen(productKey));
    393     memcpy(macSrc + strlen(macSrc), "timestamp", strlen("timestamp"));
    394     memcpy(macSrc + strlen(macSrc), TIMESTAMP_VALUE, strlen(TIMESTAMP_VALUE));
    395 
    396     utils_hmac_sha256((uint8_t *)macSrc, strlen(macSrc), (uint8_t *)deviceSecret,
    397                       strlen(deviceSecret), macRes);
    398     memset(password, 0, PASSWORD_MAXLEN);
    399     printf("password: %s
    ", password);
    400     _hex2str(macRes, sizeof(macRes), password);
    401     return 0;
    402 }

    qt窗口使用的是qwidget,继承的子类名称为myWidget,myWidget.cpp

    代码为:

    #include "mywidget.h"
    #include <QFont>
    #include "hmac.h"
    #include "stdio.h"
    #include "string.h"
    myWidget::myWidget(QWidget *parent)
        : QWidget(parent)
    {
        this->resize(1000,500);
        setWindowTitle("阿里登录信息计算器");
        QFont font;
        font.setPointSize(10);
        setFont(font);
        m_but=new QPushButton("计算",this);
    
        label_pwd=new QLabel("password",this);
        label_pwd->move(0,0);
        label_pwd->resize(1000,30);
        label_pwd->setStyleSheet("background-color:red");
        m_pwd=new QLineEdit(this);
        m_pwd->move(0,30);
        m_pwd->resize(1000,30);
        //m_pwd->setText("password");
    
        label_id=new QLabel("clientId",this);
        label_id->move(0,60);
        label_id->resize(1000,30);
        label_id->setStyleSheet("background-color:yellow");
        m_id=new QLineEdit(this);
        m_id->move(0,90);
        m_id->resize(1000,30);
    //    m_id->setText("clientId");
    
        label_user=new QLabel("username",this);
        label_user->move(0,120);
        label_user->resize(1000,30);
        label_user->setStyleSheet("background-color:red");
        m_name=new QLineEdit(this);
        m_name->move(0,150);
        m_name->resize(1000,30);
        //m_name->setText("username");
    
        QFont font1("Microsoft",10,75);
    
        label_tip=new QLabel("请输入以下参数:",this);
        label_tip->setFont(font1);
    
        label_tip->move(0,200);
        label_tip->resize(1000,30);
        //label_tip->setStyleSheet("background-color:yellow");
    
        label_key=new QLabel("productkey",this);
        label_key->move(0,230);
        label_key->resize(1000,30);
        label_key->setStyleSheet("background-color:red");
        m_prd_key=new QLineEdit("a1Fk4iW6xld",this);
        m_prd_key->move(0,260);
        m_prd_key->resize(1000,30);
    
        label_srt=new QLabel("deviceserect",this);
        label_srt->move(0,290);
        label_srt->resize(1000,30);
        label_srt->setStyleSheet("background-color:yellow");
        m_dev_srt=new QLineEdit("SbsnTLdS1GKGEsHUDIA9V1AJJ1FvV1dp",this);
        m_dev_srt->move(0,320);
        m_dev_srt->resize(1000,30);
    
        label_name=new QLabel("devicename",this);
        label_name->move(0,350);
        label_name->resize(1000,30);
        label_name->setStyleSheet("background-color:red");
        m_dev_name=new QLineEdit("powermac",this);
        m_dev_name->move(0,380);
        m_dev_name->resize(1000,30);
        m_but->move(0,410);
    
        m_but->resize(150,50);
        m_brower=new QMessageBox(this);
        m_layout=new QHBoxLayout(this);
    
        connect(m_but,SIGNAL(clicked()),this,SLOT(calpwd()));
    }
    
    myWidget::~myWidget()
    {
    }
    void myWidget::calpwd(void){
        char clientId[150] = {0};
        char username[65] = {0};
        char password[65] = {0};
    
    
        QByteArray prd_key;
        prd_key.append(this->m_prd_key->text());
    
        QByteArray dev_name;
        dev_name.append(this->m_dev_name->text());
        QByteArray dev_srt;
        dev_srt.append(this->m_dev_srt->text());
    
        aiotMqttSign(prd_key.data(),dev_name.data(),dev_srt.data(), clientId, username, password);
    
    
        this->m_pwd->setText(password);
        this->m_id->setText(clientId);
        this->m_name->setText(username);
        printf("clientid: %s
    ", clientId);
        printf("username: %s
    ", username);
        printf("password: %s
    ", password);
    }

    需要注意的问题为 用的阿里云算法接口中传进去的参数类型为char *,qt QLineEdit空间返回的数据类型为QString 类型,转化方式为借助QByteArray

    代码为:

     QByteArray prd_key;
        prd_key.append(this->m_prd_key->text());
    
        QByteArray dev_name;
        dev_name.append(this->m_dev_name->text());
        QByteArray dev_srt;
        dev_srt.append(this->m_dev_srt->text());
    
        aiotMqttSign(prd_key.data(),dev_name.data(),dev_srt.data(), clientId, username, password);
    他只是向前航行,脚下是沉静碧蓝的大海,而头顶是金色的太阳。
  • 相关阅读:
    引用类型中的push()、pop()、shift()方法
    SQL Server ->>监控和管理Tempdb
    SQL Server ->> 与SQL Server服务配置相关的DMV
    SQL Server ->> 深入探讨SQL Server 2016新特性之 --- Temporal Table(历史表)
    SQL Server ->> 深入探讨SQL Server 2016新特性之 --- Row-Level Security(行级别安全控制)
    SQL Server ->> SQL Server 2016新特性之 -- sp_set_session_context存储过程和SESSION_CONTEXT函数
    SQL Server ->> Enable Instant File Initialization(开启文件及时初始化)
    SQL Server ->> 尝试优化ETL中优化Merge性能
    SQL Server ->> 校检函数CHECKSUM、CHECKSUM_AGG、BINARY_CHECKSUM和HASHBYTES
    SQL Server ->> Database Promgramming Object Security Control(数据库编程对象安全控制)
  • 原文地址:https://www.cnblogs.com/bliss-/p/12510651.html
Copyright © 2020-2023  润新知