腾讯物联网云平台 密钥 MQTT参数生成及密码加密算法实现
腾讯云三元组腾讯云三元组
首先在腾讯物联网云平台创建好项目、产品、设备,然后获取该设备的三元组。下面通过我的创建的产品作为示例:
ProductID:IAYFFH3EO2
DeviceName:dev3
DeviceSecret: xjOShbtCetQmvEaJ75RJ1g==
#获取clinetID、Username、Password
clientID:IAYFFH3EO2dev3(ProductID+DeviceName)
Username:IAYFFH3EO2dev3;1126;HD3CI;1635759071(clientid;{clientid};clientid;{sdkappid};connid;{connid};connid;{expiry})
sdkappid、connid可随机生成,但注意字符个数sdkappid为8个字符,connid为5个字符。expiry为失效时间戳,即超过该时间戳后该密钥失效。Username可通过后面的加密算法自动生成,不需要自行生成。
Password:password 是由Username和DeviceSecret进行hmacSha1或者hmacSha256生成的,而且DeviceSecret是通过base64加密生成的,在生成Password前需要DeviceSecret解密base64,再进行hmacSha1或者hmacSha256加密生成。
腾讯云也提供了几种语言的算法实现,目前试过python的脚本是hmacsha256算法脚本且能正常生成参数但是我们是进行C开发的所以不适合通过调用python脚本来生成。其提供的C是hmacsha1算法但是工程不完整的而且是HAL平台的。本人通过下载腾讯云的sdk将一部分代码提取了出来,实现c通过hmacsha1算法生成clientID、Username、Password。
test.c
#include "limits.h"#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include "utils_base64.h"#include "utils_hmac.h"#include <time.h>#include <string.h>/* Max size of base64 encoded PSK = 64, after decode: 64/4*3 = 48*/#define DECODE_PSK_LENGTH 48/* MAX valid time when connect to MQTT server. 0: always valid *//* Use this only if the device has accurate UTC time. Otherwise, set to 0 */#define MAX_ACCESS_EXPIRE_TIMEOUT (60 * 1000) //过期时间我这里设置的是1分钟,只要每次连接前都生成一次这里可以设置为0/* Max size of conn Id */#define MAX_CONN_ID_LEN (6)/* IoT C-SDK APPID */#define QCLOUD_IOT_DEVICE_SDK_APPID"1126" //sdkappid设置的固定值#define QCLOUD_IOT_DEVICE_SDK_APPID_LEN (sizeof(QCLOUD_IOT_DEVICE_SDK_APPID) - 1)static void HexDump(uint8_t *pData, uint16_t len){int i;for (i = 0; i < len; i++) {if (i % 32 == 0) {printf("\n");}printf(" %02X", pData[i]);}printf("\n");}int main(int argc, char **argv){char *product_id = NULL;char *device_name = NULL;char *device_secret = NULL;char *username= NULL;int username_len = 0;char conn_id[MAX_CONN_ID_LEN];char password[51]= {0};char username_sign[41] = {0};char psk_base64decode[DECODE_PSK_LENGTH];size_t psk_base64decode_len = 0;long cur_timestamp = 0;if (argc != 4) {printf("please ./qcloud-mqtt-sign product_id device_name device_secret\r\n");return -1;}product_id = argv[1];device_name = argv[2];device_secret = argv[3];/* first device_secret base64 decode */qcloud_iot_utils_base64decode((unsigned char *)psk_base64decode, DECODE_PSK_LENGTH, &psk_base64decode_len,(unsigned char *)device_secret, strlen(device_secret));//base64_decode(device_secret, psk_base64decode);printf("device_secret base64 decode:");HexDump(psk_base64decode, psk_base64decode_len);/* second create mqtt username* [productdevicename;appid;randomconnid;timestamp] */cur_timestamp = time(NULL) + MAX_ACCESS_EXPIRE_TIMEOUT / 1000;if (cur_timestamp <= 0 || MAX_ACCESS_EXPIRE_TIMEOUT <= 0) {cur_timestamp = LONG_MAX;}// 20 for timestampe length & delimiterusername_len = strlen(product_id) + strlen(device_name) + QCLOUD_IOT_DEVICE_SDK_APPID_LEN + MAX_CONN_ID_LEN + 20;username= (char *)malloc(username_len);if (username == NULL) {printf("malloc username failed!\r\n");return -1;}snprintf(username, username_len, "%s%s;%s;%s;%ld", product_id, device_name, QCLOUD_IOT_DEVICE_SDK_APPID,"HD3CI", cur_timestamp); //connid设置的固定值HD3CI/* third use psk_base64decode hamc_sha1 calc mqtt username sign crate mqtt* password */utils_hmac_sha1(username, strlen(username), username_sign, psk_base64decode, psk_base64decode_len);//Hmacsha256_enc(psk_base64decode,psk_base64decode_len,username,strlen(username),username_sign);printf("username sign: %s\r\n", username_sign);snprintf(password, 51, "%s;hmacsha1", username_sign);printf("Client ID: %s%s\r\n", product_id, device_name);printf("username : %s\r\n", username);printf("password : %s\r\n", password);free(username);return 0;}
utils_base64.c
/** Tencent is pleased to support the open source community by making IoT Hubavailable.* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.* Licensed under the MIT License (the "License"); you may not use this fileexcept in* compliance with the License. You may obtain a copy of the License at* /licenses/MIT* Unless required by applicable law or agreed to in writing, softwaredistributed under the License is* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,* either express or implied. See the License for the specific languagegoverning permissions and* limitations under the License.**/#ifdef __cplusplusextern "C" {#endif#include "utils_base64.h"#include <stdint.h>#include <stdlib.h>static const unsigned char base64_enc_map[64] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V','W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r','s', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};static const unsigned char base64_dec_map[128] = {127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 62,127, 127, 127, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, 127, 64, 127, 127, 127, 0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,23, 24, 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 127, 127, 127, 127, 127};#define BASE64_SIZE_T_MAX ((size_t)-1) /* SIZE_T_MAX is not standard */int qcloud_iot_utils_base64encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen){size_t i, n;unsigned char *p;if (slen == 0) {*olen = 0;return (0);}n = slen / 3 + (slen % 3 != 0);if (n > (BASE64_SIZE_T_MAX - 1) / 4) {*olen = BASE64_SIZE_T_MAX;return (QCLOUD_ERR_FAILURE);}n *= 4;if ((dlen < n + 1) || (NULL == dst)) {*olen = n + 1;return (QCLOUD_ERR_FAILURE);}n = (slen / 3) * 3;int C1, C2, C3;for (i = 0, p = dst; i < n; i += 3) {C1 = *src++;C2 = *src++;C3 = *src++;*p++ = base64_enc_map[(C1 >> 2) & 0x3F];*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];*p++ = base64_enc_map[C3 & 0x3F];}if (i < slen) {C1 = *src++;C2 = ((i + 1) < slen) ? *src++ : 0;*p++ = base64_enc_map[(C1 >> 2) & 0x3F];*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];if ((i + 1) < slen)*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];else*p++ = '=';*p++ = '=';}*olen = p - dst;*p = 0;return (0);}int qcloud_iot_utils_base64decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen){size_t i, n;uint32_t j, x;unsigned char *p;/* First pass: check for validity and get output length */for (i = n = j = 0; i < slen; i++) {/* Skip spaces before checking for EOL */x = 0;while (i < slen && src[i] == ' ') {++i;++x;}/* Spaces at end of buffer are OK */if (i == slen)break;if ((slen - i) >= 2 && src[i] == '\r' && src[i + 1] == '\n')continue;if (src[i] == '\n')continue;/* Space inside a line is an error */if (x != 0)return (QCLOUD_ERR_FAILURE);if (src[i] == '=' && ++j > 2)return (QCLOUD_ERR_FAILURE);if (src[i] > 127 || base64_dec_map[src[i]] == 127)return (QCLOUD_ERR_FAILURE);if (base64_dec_map[src[i]] < 64 && j != 0)return (QCLOUD_ERR_FAILURE);n++;}if (n == 0) {*olen = 0;return (0);}n = ((n * 6) + 7) >> 3;n -= j;if (dst == NULL || dlen < n) {*olen = n;return (QCLOUD_ERR_FAILURE);}for (j = 3, n = x = 0, p = dst; i > 0; i--, src++) {if (*src == '\r' || *src == '\n' || *src == ' ')continue;j -= (base64_dec_map[*src] == 64);x = (x << 6) | (base64_dec_map[*src] & 0x3F);if (++n == 4) {n = 0;if (j > 0)*p++ = (unsigned char)(x >> 16);if (j > 1)*p++ = (unsigned char)(x >> 8);if (j > 2)*p++ = (unsigned char)(x);}}*olen = p - dst;return (0);}#ifdef __cplusplus}#endif
utils_base64.h
/** Tencent is pleased to support the open source community by making IoT Hubavailable.* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.* Licensed under the MIT License (the "License"); you may not use this fileexcept in* compliance with the License. You may obtain a copy of the License at* /licenses/MIT* Unless required by applicable law or agreed to in writing, softwaredistributed under the License is* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,* either express or implied. See the License for the specific languagegoverning permissions and* limitations under the License.**/#ifndef QCLOUD_IOT_UTILS_BASE64_H_#define QCLOUD_IOT_UTILS_BASE64_H_#ifdef __cplusplusextern "C" {#endif#include <stdio.h>#include "qcloud_iot_export_error.h"int qcloud_iot_utils_base64encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen);int qcloud_iot_utils_base64decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen);#ifdef __cplusplus}#endif#endif /* QCLOUD_IOT_UTILS_BASE64_H_ */
qcloud_iot_export_error.h
/** Tencent is pleased to support the open source community by making IoT Hubavailable.* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.* Licensed under the MIT License (the "License"); you may not use this fileexcept in* compliance with the License. You may obtain a copy of the License at* /licenses/MIT* Unless required by applicable law or agreed to in writing, softwaredistributed under the License is* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,* either express or implied. See the License for the specific languagegoverning permissions and* limitations under the License.**/#ifndef QCLOUD_IOT_EXPORT_ERROR_H_#define QCLOUD_IOT_EXPORT_ERROR_H_#ifdef __cplusplusextern "C" {#endif/*** IOT SDK return/error code* Enumeration of return code in QCloud IoT C-SDK.* Values less than 0 are specific error codes* Value of 0 is successful return* Values greater than 0 are specific non-error return codes*/typedef enum {QCLOUD_RET_MQTT_ALREADY_CONNECTED = 4, // Already connected with MQTT serverQCLOUD_RET_MQTT_CONNACK_CONNECTION_ACCEPTED = 3, // MQTT connection accepted by serverQCLOUD_RET_MQTT_MANUALLY_DISCONNECTED = 2, // Manually disconnected with MQTT serverQCLOUD_RET_MQTT_RECONNECTED = 1, // Reconnected with MQTT server successfullyQCLOUD_RET_SUCCESS = 0, // Successful returnQCLOUD_ERR_FAILURE = -1001, // Generic failure returnQCLOUD_ERR_INVAL = -1002, // Invalid parameterQCLOUD_ERR_DEV_INFO = -1003, // Fail to get device infoQCLOUD_ERR_MALLOC = -1004, // Fail to malloc memoryQCLOUD_ERR_HTTP_CLOSED = -3, // HTTP server close the connectionQCLOUD_ERR_HTTP= -4, // HTTP unknown errorQCLOUD_ERR_HTTP_PRTCL= -5, // HTTP protocol errorQCLOUD_ERR_HTTP_UNRESOLVED_DNS = -6, // HTTP DNS resolve failedQCLOUD_ERR_HTTP_PARSE= -7, // HTTP URL parse failedQCLOUD_ERR_HTTP_CONN = -8, // HTTP connect failedQCLOUD_ERR_HTTP_AUTH = -9, // HTTP auth failedQCLOUD_ERR_HTTP_NOT_FOUND= -10, // HTTP 404QCLOUD_ERR_HTTP_TIMEOUT = -11, // HTTP timeoutQCLOUD_ERR_MQTT_PUSH_TO_LIST_FAILED = -102, // Fail to push node to MQTT waiting listQCLOUD_ERR_MQTT_NO_CONN = -103, // Not connected with MQTT serverQCLOUD_ERR_MQTT_UNKNOWN = -104, // MQTT unknown errorQCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT = -105, // Reconnecting with MQTT serverQCLOUD_ERR_MQTT_RECONNECT_TIMEOUT = -106, // MQTT reconnect timeoutQCLOUD_ERR_MQTT_MAX_SUBSCRIPTIONS = -107, // MQTT topic subscription out of rangeQCLOUD_ERR_MQTT_SUB= -108, // MQTT topic subscription failQCLOUD_ERR_MQTT_NOTHING_TO_READ = -109, // MQTT nothing to readQCLOUD_ERR_MQTT_PACKET_READ = -110, // Something wrong when reading MQTT packetQCLOUD_ERR_MQTT_REQUEST_TIMEOUT = -111, // MQTT request timeoutQCLOUD_ERR_MQTT_CONNACK_UNKNOWN = -112, // MQTT connection refused: unknown errorQCLOUD_ERR_MQTT_CONNACK_UNACCEPTABLE_PROTOCOL_VERSION = -113, // MQTT connection refused: protocol version invalidQCLOUD_ERR_MQTT_CONNACK_IDENTIFIER_REJECTED = -114, // MQTT connection refused: identifier rejectedQCLOUD_ERR_MQTT_CONNACK_SERVER_UNAVAILABLE = -115, // MQTT connection refused: service not availableQCLOUD_ERR_MQTT_CONNACK_BAD_USERDATA = -116, // MQTT connection refused: bad user name or passwordQCLOUD_ERR_MQTT_CONNACK_NOT_AUTHORIZED= -117, // MQTT connection refused: not authorizedQCLOUD_ERR_RX_MESSAGE_INVAL = -118, // MQTT received invalid msgQCLOUD_ERR_BUF_TOO_SHORT= -119, // MQTT recv buffer not enoughQCLOUD_ERR_MQTT_QOS_NOT_SUPPORT = -120, // MQTT QoS level not supportedQCLOUD_ERR_MQTT_UNSUB_FAIL = -121, // MQTT unsubscribe failedQCLOUD_ERR_JSON_PARSE = -132, // JSON parsing errorQCLOUD_ERR_JSON_BUFFER_TRUNCATED = -133, // JSON buffer truncatedQCLOUD_ERR_JSON_BUFFER_TOO_SMALL = -134, // JSON parsing buffer not enoughQCLOUD_ERR_JSON = -135, // JSON generation errorQCLOUD_ERR_MAX_JSON_TOKEN = -136, // JSON token out of rangeQCLOUD_ERR_MAX_APPENDING_REQUEST = -137, // appending request out of rangeQCLOUD_ERR_MAX_TOPIC_LENGTH= -138, // Topic length oversizeQCLOUD_ERR_COAP_NULL = -150, // COAP null pointerQCLOUD_ERR_COAP_DATA_SIZE = -151, // COAP data size out of rangeQCLOUD_ERR_COAP_INTERNAL= -152, // COAP interval errorQCLOUD_ERR_COAP_BADMSG = -153, // COAP bad msgQCLOUD_ERR_DTLS_PEER_CLOSE_NOTIFY = -160, // DTLS connection is closedQCLOUD_ERR_PROPERTY_EXIST= -201, // property already existQCLOUD_ERR_NOT_PROPERTY_EXIST = -202, // property not existQCLOUD_ERR_REPORT_TIMEOUT= -203, // update timeoutQCLOUD_ERR_REPORT_REJECTED = -204, // update rejected by serverQCLOUD_ERR_GET_TIMEOUT = -205, // get timeoutQCLOUD_ERR_GET_REJECTED = -206, // get rejected by serverQCLOUD_ERR_ACTION_EXIST= -210, // acion already existQCLOUD_ERR_NOT_ACTION_EXIST = -211, // acion not existQCLOUD_ERR_GATEWAY_CREATE_SESSION_FAIL = -221, // Gateway fail to create sub-device sessionQCLOUD_ERR_GATEWAY_SESSION_NO_EXIST = -222, // Gateway sub-device session not existQCLOUD_ERR_GATEWAY_SESSION_TIMEOUT= -223, // Gateway sub-device session timeoutQCLOUD_ERR_GATEWAY_SUBDEV_ONLINE = -224, // Gateway sub-device onlineQCLOUD_ERR_GATEWAY_SUBDEV_OFFLINE= -225, // Gateway sub-device offlineQCLOUD_ERR_TCP_SOCKET_FAILED = -601, // TLS TCP socket connect failQCLOUD_ERR_TCP_UNKNOWN_HOST = -602, // TCP unknown host (DNS fail)QCLOUD_ERR_TCP_CONNECT = -603, // TCP/UDP socket connect failQCLOUD_ERR_TCP_READ_TIMEOUT = -604, // TCP read timeoutQCLOUD_ERR_TCP_WRITE_TIMEOUT = -605, // TCP write timeoutQCLOUD_ERR_TCP_READ_FAIL = -606, // TCP read errorQCLOUD_ERR_TCP_WRITE_FAIL= -607, // TCP write errorQCLOUD_ERR_TCP_PEER_SHUTDOWN = -608, // TCP server close connectionQCLOUD_ERR_TCP_NOTHING_TO_READ = -609, // TCP socket nothing to readQCLOUD_ERR_SSL_INIT = -701, // TLS/SSL init failQCLOUD_ERR_SSL_CERT = -702, // TLS/SSL certificate issueQCLOUD_ERR_SSL_CONNECT = -703, // TLS/SSL connect failQCLOUD_ERR_SSL_CONNECT_TIMEOUT = -704, // TLS/SSL connect timeoutQCLOUD_ERR_SSL_WRITE_TIMEOUT = -705, // TLS/SSL write timeoutQCLOUD_ERR_SSL_WRITE = -706, // TLS/SSL write errorQCLOUD_ERR_SSL_READ_TIMEOUT = -707, // TLS/SSL read timeoutQCLOUD_ERR_SSL_READ = -708, // TLS/SSL read errorQCLOUD_ERR_SSL_NOTHING_TO_READ = -709, // TLS/SSL nothing to readQCLOUD_ERR_BIND_PARA_ERR = -801, // bind sub device param errorQCLOUD_ERR_BIND_SUBDEV_ERR= -802, // sub device not exist or illegalQCLOUD_ERR_BIND_SIGN_ERR = -803, // signature check errQCLOUD_ERR_BIND_SIGN_METHOD_RRR = -804, // signmethod not supporteQCLOUD_ERR_BIND_SIGN_EXPIRED = -805, // signature expiredQCLOUD_ERR_BIND_BEEN_BINDED= -806, // sub device has been binded by other gatewayQCLOUD_ERR_BIND_SUBDEV_FORBID = -807, // sub device not allow to bindQCLOUD_ERR_BIND_OP_FORBID = -808, // operation not permitQCLOUD_ERR_BIND_REPEATED_REQ = -809, // repeated bind request,has been binded} IoT_Return_Code;#ifdef __cplusplus}#endif#endif /* QCLOUD_IOT_EXPORT_ERROR_H_ */
utils_hmac.c
/** Tencent is pleased to support the open source community by making IoT Hubavailable.* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.* Licensed under the MIT License (the "License"); you may not use this fileexcept in* compliance with the License. You may obtain a copy of the License at* /licenses/MIT* Unless required by applicable law or agreed to in writing, softwaredistributed under the License is* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,* either express or implied. See the License for the specific languagegoverning permissions and* limitations under the License.**/#include <stdint.h>#include "utils_hmac.h"#include <string.h>#include "utils_md5.h"#include "utils_sha1.h"#define KEY_IOPAD_SIZE 64#define MD5_DIGEST_SIZE 16#define SHA1_DIGEST_SIZE 20void utils_hmac_md5(const char *msg, int msg_len, char *digest, const char *key, int key_len){if ((NULL == msg) || (NULL == digest) || (NULL == key)) {//Log_e("parameter is Null,failed!");return;}if (key_len > KEY_IOPAD_SIZE) {//Log_e("key_len > size(%d) of array", KEY_IOPAD_SIZE);return;}iot_md5_context context;unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */unsigned char out[MD5_DIGEST_SIZE];int i;/* start out by storing key in pads */memset(k_ipad, 0, sizeof(k_ipad));memset(k_opad, 0, sizeof(k_opad));memcpy(k_ipad, key, key_len);memcpy(k_opad, key, key_len);/* XOR key with ipad and opad values */for (i = 0; i < KEY_IOPAD_SIZE; i++) {k_ipad[i] ^= 0x36;k_opad[i] ^= 0x5c;}/* perform inner MD5 */utils_md5_init(&context); /* init context for 1st pass */utils_md5_starts(&context); /* setup context for 1st pass */utils_md5_update(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */utils_md5_update(&context, (unsigned char *)msg, msg_len); /* then text of datagram */utils_md5_finish(&context, out); /* finish up 1st pass *//* perform outer MD5 */utils_md5_init(&context); /* init context for 2nd pass */utils_md5_starts(&context);/* setup context for 2nd pass */utils_md5_update(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */utils_md5_update(&context, out, MD5_DIGEST_SIZE); /* then results of 1st hash */utils_md5_finish(&context, out);/* finish up 2nd pass */for (i = 0; i < MD5_DIGEST_SIZE; ++i) {digest[i * 2]= utils_hb2hex(out[i] >> 4);digest[i * 2 + 1] = utils_hb2hex(out[i]);}}void utils_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len){if ((NULL == msg) || (NULL == digest) || (NULL == key)) {//Log_e("parameter is Null,failed!");return;}if (key_len > KEY_IOPAD_SIZE) {//Log_e("key_len > size(%d) of array", KEY_IOPAD_SIZE);return;}iot_sha1_context context;unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */unsigned char out[SHA1_DIGEST_SIZE];int i;/* start out by storing key in pads */memset(k_ipad, 0, sizeof(k_ipad));memset(k_opad, 0, sizeof(k_opad));memcpy(k_ipad, key, key_len);memcpy(k_opad, key, key_len);/* XOR key with ipad and opad values */for (i = 0; i < KEY_IOPAD_SIZE; i++) {k_ipad[i] ^= 0x36;k_opad[i] ^= 0x5c;}/* perform inner SHA */utils_sha1_init(&context); /* init context for 1st pass */utils_sha1_starts(&context); /* setup context for 1st pass */utils_sha1_update(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */utils_sha1_update(&context, (unsigned char *)msg, msg_len); /* then text of datagram */utils_sha1_finish(&context, out); /* finish up 1st pass *//* perform outer SHA */utils_sha1_init(&context); /* init context for 2nd pass */utils_sha1_starts(&context);/* setup context for 2nd pass */utils_sha1_update(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */utils_sha1_update(&context, out, SHA1_DIGEST_SIZE); /* then results of 1st hash */utils_sha1_finish(&context, out);/* finish up 2nd pass */for (i = 0; i < SHA1_DIGEST_SIZE; ++i) {digest[i * 2]= utils_hb2hex(out[i] >> 4);digest[i * 2 + 1] = utils_hb2hex(out[i]);}}int utils_hmac_sha1_hex(const char *msg, int msg_len, char *digest, const char *key, int key_len){if ((NULL == msg) || (NULL == digest) || (NULL == key)) {//Log_e("parameter is Null,failed!");return 0;}if (key_len > KEY_IOPAD_SIZE) {//Log_e("key_len > size(%d) of array", KEY_IOPAD_SIZE);return 0;}iot_sha1_context context;unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */unsigned char out[SHA1_DIGEST_SIZE];int i;/* start out by storing key in pads */memset(k_ipad, 0, sizeof(k_ipad));memset(k_opad, 0, sizeof(k_opad));memcpy(k_ipad, key, key_len);memcpy(k_opad, key, key_len);/* XOR key with ipad and opad values */for (i = 0; i < KEY_IOPAD_SIZE; i++) {k_ipad[i] ^= 0x36;k_opad[i] ^= 0x5c;}/* perform inner SHA */utils_sha1_init(&context); /* init context for 1st pass */utils_sha1_starts(&context); /* setup context for 1st pass */utils_sha1_update(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */utils_sha1_update(&context, (unsigned char *)msg, msg_len); /* then text of datagram */utils_sha1_finish(&context, out); /* finish up 1st pass *//* perform outer SHA */utils_sha1_init(&context); /* init context for 2nd pass */utils_sha1_starts(&context);/* setup context for 2nd pass */utils_sha1_update(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */utils_sha1_update(&context, out, SHA1_DIGEST_SIZE); /* then results of 1st hash */utils_sha1_finish(&context, out);/* finish up 2nd pass */memcpy(digest, out, SHA1_DIGEST_SIZE);return SHA1_DIGEST_SIZE;}
utils_hmac.h
/** Tencent is pleased to support the open source community by making IoT Hubavailable.* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.* Licensed under the MIT License (the "License"); you may not use this fileexcept in* compliance with the License. You may obtain a copy of the License at* /licenses/MIT* Unless required by applicable law or agreed to in writing, softwaredistributed under the License is* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,* either express or implied. See the License for the specific languagegoverning permissions and* limitations under the License.**/#ifndef QCLOUD_IOT_UTILS_HMAC_H_#define QCLOUD_IOT_UTILS_HMAC_H_#include <string.h>void utils_hmac_md5(const char *msg, int msg_len, char *digest, const char *key, int key_len);void utils_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len);int utils_hmac_sha1_hex(const char *msg, int msg_len, char *digest, const char *key, int key_len);#endif
utils_md5.c
/** Tencent is pleased to support the open source community by making IoT Hubavailable.* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.* Licensed under the MIT License (the "License"); you may not use this fileexcept in* compliance with the License. You may obtain a copy of the License at* /licenses/MIT* Unless required by applicable law or agreed to in writing, softwaredistributed under the License is* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,* either express or implied. See the License for the specific languagegoverning permissions and* limitations under the License.**/#ifdef __cplusplusextern "C" {#endif#include "utils_md5.h"#include <stdlib.h>#include <string.h>#define MD5_DIGEST_SIZE 16/* Implementation that should never be optimized out by the compiler */static void _utils_md5_zeroize(void *v, size_t n){volatile unsigned char *p = v;while (n--) *p++ = 0;}/** 32-bit integer manipulation macros (little endian)*/#ifndef IOT_MD5_GET_UINT32_LE#define IOT_MD5_GET_UINT32_LE(n, b, i) \{\(n) = ((uint32_t)(b)[(i)]) | ((uint32_t)(b)[(i) + 1] << 8) | ((uint32_t)(b)[(i) + 2] << 16) | \((uint32_t)(b)[(i) + 3] << 24); \}#endif#ifndef IOT_MD5_PUT_UINT32_LE#define IOT_MD5_PUT_UINT32_LE(n, b, i) \{\(b)[(i)]= (unsigned char)(((n)) & 0xFF); \(b)[(i) + 1] = (unsigned char)(((n) >> 8) & 0xFF); \(b)[(i) + 2] = (unsigned char)(((n) >> 16) & 0xFF); \(b)[(i) + 3] = (unsigned char)(((n) >> 24) & 0xFF); \}#endifvoid utils_md5_init(iot_md5_context *ctx){memset(ctx, 0, sizeof(iot_md5_context));}void utils_md5_free(iot_md5_context *ctx){if (ctx == NULL) {return;}_utils_md5_zeroize(ctx, sizeof(iot_md5_context));}void utils_md5_clone(iot_md5_context *dst, const iot_md5_context *src){*dst = *src;}/** MD5 context setup*/void utils_md5_starts(iot_md5_context *ctx){ctx->total[0] = 0;ctx->total[1] = 0;ctx->state[0] = 0x67452301;ctx->state[1] = 0xEFCDAB89;ctx->state[2] = 0x98BADCFE;ctx->state[3] = 0x10325476;}void utils_md5_process(iot_md5_context *ctx, const unsigned char data[64]){uint32_t X[16], A, B, C, D;IOT_MD5_GET_UINT32_LE(X[0], data, 0);IOT_MD5_GET_UINT32_LE(X[1], data, 4);IOT_MD5_GET_UINT32_LE(X[2], data, 8);IOT_MD5_GET_UINT32_LE(X[3], data, 12);IOT_MD5_GET_UINT32_LE(X[4], data, 16);IOT_MD5_GET_UINT32_LE(X[5], data, 20);IOT_MD5_GET_UINT32_LE(X[6], data, 24);IOT_MD5_GET_UINT32_LE(X[7], data, 28);IOT_MD5_GET_UINT32_LE(X[8], data, 32);IOT_MD5_GET_UINT32_LE(X[9], data, 36);IOT_MD5_GET_UINT32_LE(X[10], data, 40);IOT_MD5_GET_UINT32_LE(X[11], data, 44);IOT_MD5_GET_UINT32_LE(X[12], data, 48);IOT_MD5_GET_UINT32_LE(X[13], data, 52);IOT_MD5_GET_UINT32_LE(X[14], data, 56);IOT_MD5_GET_UINT32_LE(X[15], data, 60);#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))#define P(a, b, c, d, k, s, t)\{\a += F(b, c, d) + X[k] + t; \a = S(a, s) + b; \}A = ctx->state[0];B = ctx->state[1];C = ctx->state[2];D = ctx->state[3];#define F(x, y, z) (z ^ (x & (y ^ z)))P(A, B, C, D, 0, 7, 0xD76AA478);P(D, A, B, C, 1, 12, 0xE8C7B756);P(C, D, A, B, 2, 17, 0x242070DB);P(B, C, D, A, 3, 22, 0xC1BDCEEE);P(A, B, C, D, 4, 7, 0xF57C0FAF);P(D, A, B, C, 5, 12, 0x4787C62A);P(C, D, A, B, 6, 17, 0xA8304613);P(B, C, D, A, 7, 22, 0xFD469501);P(A, B, C, D, 8, 7, 0x698098D8);P(D, A, B, C, 9, 12, 0x8B44F7AF);P(C, D, A, B, 10, 17, 0xFFFF5BB1);P(B, C, D, A, 11, 22, 0x895CD7BE);P(A, B, C, D, 12, 7, 0x6B901122);P(D, A, B, C, 13, 12, 0xFD987193);P(C, D, A, B, 14, 17, 0xA679438E);P(B, C, D, A, 15, 22, 0x49B40821);#undef F#define F(x, y, z) (y ^ (z & (x ^ y)))P(A, B, C, D, 1, 5, 0xF61E2562);P(D, A, B, C, 6, 9, 0xC040B340);P(C, D, A, B, 11, 14, 0x265E5A51);P(B, C, D, A, 0, 20, 0xE9B6C7AA);P(A, B, C, D, 5, 5, 0xD62F105D);P(D, A, B, C, 10, 9, 0x02441453);P(C, D, A, B, 15, 14, 0xD8A1E681);P(B, C, D, A, 4, 20, 0xE7D3FBC8);P(A, B, C, D, 9, 5, 0x21E1CDE6);P(D, A, B, C, 14, 9, 0xC33707D6);P(C, D, A, B, 3, 14, 0xF4D50D87);P(B, C, D, A, 8, 20, 0x455A14ED);P(A, B, C, D, 13, 5, 0xA9E3E905);P(D, A, B, C, 2, 9, 0xFCEFA3F8);P(C, D, A, B, 7, 14, 0x676F02D9);P(B, C, D, A, 12, 20, 0x8D2A4C8A);#undef F#define F(x, y, z) (x ^ y ^ z)P(A, B, C, D, 5, 4, 0xFFFA3942);P(D, A, B, C, 8, 11, 0x8771F681);P(C, D, A, B, 11, 16, 0x6D9D6122);P(B, C, D, A, 14, 23, 0xFDE5380C);P(A, B, C, D, 1, 4, 0xA4BEEA44);P(D, A, B, C, 4, 11, 0x4BDECFA9);P(C, D, A, B, 7, 16, 0xF6BB4B60);P(B, C, D, A, 10, 23, 0xBEBFBC70);P(A, B, C, D, 13, 4, 0x289B7EC6);P(D, A, B, C, 0, 11, 0xEAA127FA);P(C, D, A, B, 3, 16, 0xD4EF3085);P(B, C, D, A, 6, 23, 0x04881D05);P(A, B, C, D, 9, 4, 0xD9D4D039);P(D, A, B, C, 12, 11, 0xE6DB99E5);P(C, D, A, B, 15, 16, 0x1FA27CF8);P(B, C, D, A, 2, 23, 0xC4AC5665);#undef F#define F(x, y, z) (y ^ (x | ~z))P(A, B, C, D, 0, 6, 0xF4292244);P(D, A, B, C, 7, 10, 0x432AFF97);P(C, D, A, B, 14, 15, 0xAB9423A7);P(B, C, D, A, 5, 21, 0xFC93A039);P(A, B, C, D, 12, 6, 0x655B59C3);P(D, A, B, C, 3, 10, 0x8F0CCC92);P(C, D, A, B, 10, 15, 0xFFEFF47D);P(B, C, D, A, 1, 21, 0x85845DD1);P(A, B, C, D, 8, 6, 0x6FA87E4F);P(D, A, B, C, 15, 10, 0xFE2CE6E0);P(C, D, A, B, 6, 15, 0xA3014314);P(B, C, D, A, 13, 21, 0x4E0811A1);P(A, B, C, D, 4, 6, 0xF7537E82);P(D, A, B, C, 11, 10, 0xBD3AF235);P(C, D, A, B, 2, 15, 0x2AD7D2BB);P(B, C, D, A, 9, 21, 0xEB86D391);#undef Fctx->state[0] += A;ctx->state[1] += B;ctx->state[2] += C;ctx->state[3] += D;}/** MD5 process buffer*/void utils_md5_update(iot_md5_context *ctx, const unsigned char *input, size_t ilen){size_t fill;uint32_t left;if (ilen == 0) {return;}left = ctx->total[0] & 0x3F;fill = 64 - left;ctx->total[0] += (uint32_t)ilen;ctx->total[0] &= 0xFFFFFFFF;if (ctx->total[0] < (uint32_t)ilen) {ctx->total[1]++;}if (left && ilen >= fill) {memcpy((void *)(ctx->buffer + left), input, fill);utils_md5_process(ctx, ctx->buffer);input += fill;ilen -= fill;left = 0;}while (ilen >= 64) {utils_md5_process(ctx, input);input += 64;ilen -= 64;}if (ilen > 0) {memcpy((void *)(ctx->buffer + left), input, ilen);}}static const unsigned char iot_md5_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};/** MD5 final digest*/void utils_md5_finish(iot_md5_context *ctx, unsigned char output[16]){uint32_tlast, padn;uint32_thigh, low;unsigned char msglen[8];high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);low = (ctx->total[0] << 3);IOT_MD5_PUT_UINT32_LE(low, msglen, 0);IOT_MD5_PUT_UINT32_LE(high, msglen, 4);last = ctx->total[0] & 0x3F;padn = (last < 56) ? (56 - last) : (120 - last);utils_md5_update(ctx, iot_md5_padding, padn);utils_md5_update(ctx, msglen, 8);IOT_MD5_PUT_UINT32_LE(ctx->state[0], output, 0);IOT_MD5_PUT_UINT32_LE(ctx->state[1], output, 4);IOT_MD5_PUT_UINT32_LE(ctx->state[2], output, 8);IOT_MD5_PUT_UINT32_LE(ctx->state[3], output, 12);}/** output = MD5( input buffer )*/void utils_md5(const unsigned char *input, size_t ilen, unsigned char output[16]){iot_md5_context ctx;utils_md5_init(&ctx);utils_md5_starts(&ctx);utils_md5_update(&ctx, input, ilen);utils_md5_finish(&ctx, output);utils_md5_free(&ctx);}int8_t utils_hb2hex(uint8_t hb){hb = hb & 0xF;return (int8_t)(hb < 10 ? '0' + hb : hb - 10 + 'a');}void utils_md5_str(const unsigned char *input, size_t ilen, unsigned char *output){int i;unsigned char buf_out[16];utils_md5(input, ilen, buf_out);// hex to stringfor (i = 0; i < 16; ++i) {output[i * 2]= utils_hb2hex(buf_out[i] >> 4);output[i * 2 + 1] = utils_hb2hex(buf_out[i]);}output[32] = '\0';}/** MD5 create dynamicly*/void *utils_md5_create(void){iot_md5_context *ctx = malloc(sizeof(iot_md5_context));if (NULL == ctx) {return NULL;}utils_md5_init(ctx);utils_md5_starts(ctx);return ctx;}void utils_md5_finish_str(void *ctx, char *output_str){int i;unsigned char buf_out[16];utils_md5_finish(ctx, buf_out);for (i = 0; i < 16; ++i) {output_str[i * 2]= utils_hb2hex(buf_out[i] >> 4);output_str[i * 2 + 1] = utils_hb2hex(buf_out[i]);}output_str[32] = '\0';}void utils_md5_delete(void *ctx){free(ctx);}void utils_md5_reset(void *ctx){iot_md5_context *pCtx = (iot_md5_context *)ctx;if (!pCtx) {//Log_e("invalid md5 pointer");return;}utils_md5_init(pCtx);utils_md5_starts(pCtx);return;}#ifdef __cplusplus}#endif
utils_md5.h
/** Tencent is pleased to support the open source community by making IoT Hubavailable.* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.* Licensed under the MIT License (the "License"); you may not use this fileexcept in* compliance with the License. You may obtain a copy of the License at* /licenses/MIT* Unless required by applicable law or agreed to in writing, softwaredistributed under the License is* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,* either express or implied. See the License for the specific languagegoverning permissions and* limitations under the License.**/#ifndef QCLOUD_IOT_UTILS_MD5_H_#define QCLOUD_IOT_UTILS_MD5_H_#include <stdint.h>#include <stddef.h>typedef struct {uint32_ttotal[2]; /*!< number of bytes processed */uint32_tstate[4]; /*!< intermediate digest state */unsigned char buffer[64]; /*!< data block being processed */} iot_md5_context;/*** @brief init MD5 context** @param ctx MD5 context*/void utils_md5_init(iot_md5_context *ctx);/*** @brief free MD5 context** @param ctx MD5 context*/void utils_md5_free(iot_md5_context *ctx);/*** @brief clone MD5 context** @param dst destination MD5 context* @param src source MD5 context*/void utils_md5_clone(iot_md5_context *dst, const iot_md5_context *src);/*** @brief start MD5 calculation** @param ctx MD5 context*/void utils_md5_starts(iot_md5_context *ctx);/*** @brief MD5 update** @param ctx MD5 context* @param input input data* @param ilendata length*/void utils_md5_update(iot_md5_context *ctx, const unsigned char *input, size_t ilen);/*** @brieffinish MD5 calculation** @param ctxMD5 context* @param output MD5 result*/void utils_md5_finish(iot_md5_context *ctx, unsigned char output[16]);/* MD5 internal process */void utils_md5_process(iot_md5_context *ctx, const unsigned char data[64]);/*** @briefOutput = MD5( input buffer )** @param input data input* @param ilendata length* @param output MD5 result*/void utils_md5(const unsigned char *input, size_t ilen, unsigned char output[16]);/*** @briefOutput = MD5( input buffer )** @param input data input* @param ilendata length* @param output string MD5 result*/void utils_md5_str(const unsigned char *input, size_t ilen, unsigned char *output);int8_t utils_hb2hex(uint8_t hb);/*** @briefcreate md5 context dynamic** @return MD5 context*/void *utils_md5_create(void);/*** @briefOutput = str(md5)** @param ctxMD5 ctx* @param output_str string MD5 result*/void utils_md5_finish_str(void *ctx, char *output_str);/*** @brieffree MD5 context** @param ctxMD5 ctx*/void utils_md5_delete(void *ctx);/*** @briefreset MD5 context** @param ctxMD5 ctx*/void utils_md5_reset(void *ctx);#endif
utils_sha1.c
/** Tencent is pleased to support the open source community by making IoT Hubavailable.* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.* Licensed under the MIT License (the "License"); you may not use this fileexcept in* compliance with the License. You may obtain a copy of the License at* /licenses/MIT* Unless required by applicable law or agreed to in writing, softwaredistributed under the License is* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,* either express or implied. See the License for the specific languagegoverning permissions and* limitations under the License.**/#include "utils_sha1.h"#include <stdlib.h>#include <string.h>/* Implementation that should never be optimized out by the compiler */static void utils_sha1_zeroize(void *v, size_t n){volatile unsigned char *p = v;while (n--) {*p++ = 0;}}/** 32-bit integer manipulation macros (big endian)*/#ifndef IOT_SHA1_GET_UINT32_BE#define IOT_SHA1_GET_UINT32_BE(n, b, i) \{\(n) = ((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | ((uint32_t)(b)[(i) + 2] << 8) | \((uint32_t)(b)[(i) + 3]); \}#endif#ifndef IOT_SHA1_PUT_UINT32_BE#define IOT_SHA1_PUT_UINT32_BE(n, b, i) \{\(b)[(i)]= (unsigned char)((n) >> 24); \(b)[(i) + 1] = (unsigned char)((n) >> 16); \(b)[(i) + 2] = (unsigned char)((n) >> 8); \(b)[(i) + 3] = (unsigned char)((n)); \}#endifvoid utils_sha1_init(iot_sha1_context *ctx){memset(ctx, 0, sizeof(iot_sha1_context));}void utils_sha1_free(iot_sha1_context *ctx){if (ctx == NULL) {return;}utils_sha1_zeroize(ctx, sizeof(iot_sha1_context));}void utils_sha1_clone(iot_sha1_context *dst, const iot_sha1_context *src){*dst = *src;}/** SHA-1 context setup*/void utils_sha1_starts(iot_sha1_context *ctx){ctx->total[0] = 0;ctx->total[1] = 0;ctx->state[0] = 0x67452301;ctx->state[1] = 0xEFCDAB89;ctx->state[2] = 0x98BADCFE;ctx->state[3] = 0x10325476;ctx->state[4] = 0xC3D2E1F0;}void utils_sha1_process(iot_sha1_context *ctx, const unsigned char data[64]){uint32_t temp, W[16], A, B, C, D, E;IOT_SHA1_GET_UINT32_BE(W[0], data, 0);IOT_SHA1_GET_UINT32_BE(W[1], data, 4);IOT_SHA1_GET_UINT32_BE(W[2], data, 8);IOT_SHA1_GET_UINT32_BE(W[3], data, 12);IOT_SHA1_GET_UINT32_BE(W[4], data, 16);IOT_SHA1_GET_UINT32_BE(W[5], data, 20);IOT_SHA1_GET_UINT32_BE(W[6], data, 24);IOT_SHA1_GET_UINT32_BE(W[7], data, 28);IOT_SHA1_GET_UINT32_BE(W[8], data, 32);IOT_SHA1_GET_UINT32_BE(W[9], data, 36);IOT_SHA1_GET_UINT32_BE(W[10], data, 40);IOT_SHA1_GET_UINT32_BE(W[11], data, 44);IOT_SHA1_GET_UINT32_BE(W[12], data, 48);IOT_SHA1_GET_UINT32_BE(W[13], data, 52);IOT_SHA1_GET_UINT32_BE(W[14], data, 56);IOT_SHA1_GET_UINT32_BE(W[15], data, 60);#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))#define R(t) \(temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ W[(t - 14) & 0x0F] ^ W[t & 0x0F], (W[t & 0x0F] = S(temp, 1)))#define P(a, b, c, d, e, x)\{\e += S(a, 5) + F(b, c, d) + K + x; \b = S(b, 30); \}A = ctx->state[0];B = ctx->state[1];C = ctx->state[2];D = ctx->state[3];E = ctx->state[4];#define F(x, y, z) (z ^ (x & (y ^ z)))#define K0x5A827999P(A, B, C, D, E, W[0]);P(E, A, B, C, D, W[1]);P(D, E, A, B, C, W[2]);P(C, D, E, A, B, W[3]);P(B, C, D, E, A, W[4]);P(A, B, C, D, E, W[5]);P(E, A, B, C, D, W[6]);P(D, E, A, B, C, W[7]);P(C, D, E, A, B, W[8]);P(B, C, D, E, A, W[9]);P(A, B, C, D, E, W[10]);P(E, A, B, C, D, W[11]);P(D, E, A, B, C, W[12]);P(C, D, E, A, B, W[13]);P(B, C, D, E, A, W[14]);P(A, B, C, D, E, W[15]);P(E, A, B, C, D, R(16));P(D, E, A, B, C, R(17));P(C, D, E, A, B, R(18));P(B, C, D, E, A, R(19));#undef K#undef F#define F(x, y, z) (x ^ y ^ z)#define K0x6ED9EBA1P(A, B, C, D, E, R(20));P(E, A, B, C, D, R(21));P(D, E, A, B, C, R(22));P(C, D, E, A, B, R(23));P(B, C, D, E, A, R(24));P(A, B, C, D, E, R(25));P(E, A, B, C, D, R(26));P(D, E, A, B, C, R(27));P(C, D, E, A, B, R(28));P(B, C, D, E, A, R(29));P(A, B, C, D, E, R(30));P(E, A, B, C, D, R(31));P(D, E, A, B, C, R(32));P(C, D, E, A, B, R(33));P(B, C, D, E, A, R(34));P(A, B, C, D, E, R(35));P(E, A, B, C, D, R(36));P(D, E, A, B, C, R(37));P(C, D, E, A, B, R(38));P(B, C, D, E, A, R(39));#undef K#undef F#define F(x, y, z) ((x & y) | (z & (x | y)))#define K0x8F1BBCDCP(A, B, C, D, E, R(40));P(E, A, B, C, D, R(41));P(D, E, A, B, C, R(42));P(C, D, E, A, B, R(43));P(B, C, D, E, A, R(44));P(A, B, C, D, E, R(45));P(E, A, B, C, D, R(46));P(D, E, A, B, C, R(47));P(C, D, E, A, B, R(48));P(B, C, D, E, A, R(49));P(A, B, C, D, E, R(50));P(E, A, B, C, D, R(51));P(D, E, A, B, C, R(52));P(C, D, E, A, B, R(53));P(B, C, D, E, A, R(54));P(A, B, C, D, E, R(55));P(E, A, B, C, D, R(56));P(D, E, A, B, C, R(57));P(C, D, E, A, B, R(58));P(B, C, D, E, A, R(59));#undef K#undef F#define F(x, y, z) (x ^ y ^ z)#define K0xCA62C1D6P(A, B, C, D, E, R(60));P(E, A, B, C, D, R(61));P(D, E, A, B, C, R(62));P(C, D, E, A, B, R(63));P(B, C, D, E, A, R(64));P(A, B, C, D, E, R(65));P(E, A, B, C, D, R(66));P(D, E, A, B, C, R(67));P(C, D, E, A, B, R(68));P(B, C, D, E, A, R(69));P(A, B, C, D, E, R(70));P(E, A, B, C, D, R(71));P(D, E, A, B, C, R(72));P(C, D, E, A, B, R(73));P(B, C, D, E, A, R(74));P(A, B, C, D, E, R(75));P(E, A, B, C, D, R(76));P(D, E, A, B, C, R(77));P(C, D, E, A, B, R(78));P(B, C, D, E, A, R(79));#undef K#undef Fctx->state[0] += A;ctx->state[1] += B;ctx->state[2] += C;ctx->state[3] += D;ctx->state[4] += E;}/** SHA-1 process buffer*/void utils_sha1_update(iot_sha1_context *ctx, const unsigned char *input, size_t ilen){size_t fill;uint32_t left;if (ilen == 0) {return;}left = ctx->total[0] & 0x3F;fill = 64 - left;ctx->total[0] += (uint32_t)ilen;ctx->total[0] &= 0xFFFFFFFF;if (ctx->total[0] < (uint32_t)ilen) {ctx->total[1]++;}if (left && ilen >= fill) {memcpy((void *)(ctx->buffer + left), input, fill);utils_sha1_process(ctx, ctx->buffer);input += fill;ilen -= fill;left = 0;}while (ilen >= 64) {utils_sha1_process(ctx, input);input += 64;ilen -= 64;}if (ilen > 0) {memcpy((void *)(ctx->buffer + left), input, ilen);}}static const unsigned char iot_sha1_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};/** SHA-1 final digest*/void utils_sha1_finish(iot_sha1_context *ctx, unsigned char output[20]){uint32_tlast, padn;uint32_thigh, low;unsigned char msglen[8];high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);low = (ctx->total[0] << 3);IOT_SHA1_PUT_UINT32_BE(high, msglen, 0);IOT_SHA1_PUT_UINT32_BE(low, msglen, 4);last = ctx->total[0] & 0x3F;padn = (last < 56) ? (56 - last) : (120 - last);utils_sha1_update(ctx, iot_sha1_padding, padn);utils_sha1_update(ctx, msglen, 8);IOT_SHA1_PUT_UINT32_BE(ctx->state[0], output, 0);IOT_SHA1_PUT_UINT32_BE(ctx->state[1], output, 4);IOT_SHA1_PUT_UINT32_BE(ctx->state[2], output, 8);IOT_SHA1_PUT_UINT32_BE(ctx->state[3], output, 12);IOT_SHA1_PUT_UINT32_BE(ctx->state[4], output, 16);}/** output = SHA-1( input buffer )*/void utils_sha1(const unsigned char *input, size_t ilen, unsigned char output[20]){iot_sha1_context ctx;utils_sha1_init(&ctx);utils_sha1_starts(&ctx);utils_sha1_update(&ctx, input, ilen);utils_sha1_finish(&ctx, output);utils_sha1_free(&ctx);}
utils_sha1.h
/** Tencent is pleased to support the open source community by making IoT Hubavailable.* Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.* Licensed under the MIT License (the "License"); you may not use this fileexcept in* compliance with the License. You may obtain a copy of the License at* /licenses/MIT* Unless required by applicable law or agreed to in writing, softwaredistributed under the License is* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,* either express or implied. See the License for the specific languagegoverning permissions and* limitations under the License.**/#ifndef QCLOUD_IOT_UTILS_SHA1_H_#define QCLOUD_IOT_UTILS_SHA1_H_#include <stdint.h>#include <stddef.h>/*** \briefSHA-1 context structure*/typedef struct {uint32_ttotal[2]; /*!< number of bytes processed */uint32_tstate[5]; /*!< intermediate digest state */unsigned char buffer[64]; /*!< data block being processed */} iot_sha1_context;/*** \briefInitialize SHA-1 context** \param ctxSHA-1 context to be initialized*/void utils_sha1_init(iot_sha1_context *ctx);/*** \briefClear SHA-1 context** \param ctxSHA-1 context to be cleared*/void utils_sha1_free(iot_sha1_context *ctx);/*** \briefClone (the state of) a SHA-1 context** \param dstThe destination context* \param srcThe context to be cloned*/void utils_sha1_clone(iot_sha1_context *dst, const iot_sha1_context *src);/*** \briefSHA-1 context setup** \param ctxcontext to be initialized*/void utils_sha1_starts(iot_sha1_context *ctx);/*** \briefSHA-1 process buffer** \param ctxSHA-1 context* \param input buffer holding the data* \param ilenlength of the input data*/void utils_sha1_update(iot_sha1_context *ctx, const unsigned char *input, size_t ilen);/*** \briefSHA-1 final digest** \param ctxSHA-1 context* \param output SHA-1 checksum result*/void utils_sha1_finish(iot_sha1_context *ctx, unsigned char output[20]);/* Internal use */void utils_sha1_process(iot_sha1_context *ctx, const unsigned char data[64]);/*** \briefOutput = SHA-1( input buffer )** \param input buffer holding the data* \param ilenlength of the input data* \param output SHA-1 checksum result*/void utils_sha1(const unsigned char *input, size_t ilen, unsigned char output[20]);#endif
编译:gcc -o test test.c utils_base64.c utils_sha1.c utils_md5.c utils_hmac.c
执行:./test “IAYFFH3EO2” “dev3” “xjOShbtCetQmvEaJ75RJ1g==”
结果:
这里只是生成对应的参数,如需应用到自己的工程里还需做相应的移植。