我正在尝试生成一个SAS令牌,以便使用IoT框架https://tasmota.github.io/中的PubSub客户端向Azure Azure集线器进行身份验证。
下面是一个示例:https://github.com/Azure/azure-sdk-for-c/blob/master/sdk/samples/iot/aziot_esp8266/aziot_esp8266.ino,与已知良好的Python示例相比,我只能为4个字符的秘密创建签名。当我增加或减少密钥的长度时,散列不匹配。任何关于我做错了什么的建议都将是很好的。
看起来它只是对前4个字符进行了散列和编码(注意C代码'mark‘= 'markmark')。
C代码(在ESP8266上运行):
#include <bearssl\bearssl.h> // from https://github.com/arendst/Tasmota/tree/development/lib/lib_ssl
#include <base64.hpp> // from https://github.com/arendst/Tasmota/tree/development/lib/lib_ssl
const char *PSK = "MBXjqeJm6jNEGa7TvqIEkbRHbRP+U1QhXgxR1+QGoM4=";
const char *dataToSign = "mark";
br_sha256_context sha256_context;
br_hmac_key_context hmac_key_context;
br_hmac_context hmac_context;
unsigned char decodedPSK[32];
unsigned char encryptedSignature[100];
unsigned char encodedSignature[100];
// need to base64 decode the Preshared key and the length
int base64_decoded_device_length = decode_base64((unsigned char*)PSK, decodedPSK);
// create the sha256 hmac and hash the data
br_sha256_init(&sha256_context);
br_hmac_key_init(&hmac_key_context, sha256_context.vtable, decodedPSK, base64_decoded_device_length);
br_hmac_init(&hmac_context, &hmac_key_context, 32);
br_hmac_update(&hmac_context, dataToSign, sizeof(dataToSign));
br_hmac_out(&hmac_context, encryptedSignature);
// base64 decode the HMAC to a char
encode_base64(encryptedSignature, br_hmac_size(&hmac_context), encodedSignature);
printf("PSK is %s \n", PSK);
printf("decodedPSK is %s \n", decodedPSK);
printf("dataToSign is %s \n", dataToSign);
printf("encryptedSignature is %s \n", encryptedSignature);
printf("encodedSignature is %s \n", encodedSignature);Python代码:
from base64 import b64encode, b64decode
from hashlib import sha256
from urllib.parse import quote_plus, urlencode
from hmac import HMAC
PSK="MBXjqeJm6jNEGa7TvqIEkbRHbRP+U1QhXgxR1+QGoM4="
sign_key = "mark".encode('utf-8')
signature = b64encode(HMAC(b64decode(PSK), sign_key, sha256).digest())
print('PSK = ' + PSK)
print('sign_key = ' + str(sign_key))
print('signature = ' + str(signature))如果将dataToSign设置为mark,则哈希匹配:
C输出:
PSK is MBXjqeJm6jNEGa7TvqIEkbRHbRP+U1QhXgxR1+QGoM4=
ecodedPSK is 0␕��f�3D␙�Ӿ�␄��Gm␓�ST!^␌Q��␆��
dataToSign is mark
encryptedSignature is ␝�8)����jLQ��␃b!��x␞Ǿ2��1�W␗S4���?���?�␕�?
encodedSignature is Hak4Kaic0vtqTFGSlQNiIeeD6ngex74yoOExgVcXUzQ=Python输出:
C:/Python38-64/python.exe d:/Git/createsastoken/generate/test.py
PSK = MBXjqeJm6jNEGa7TvqIEkbRHbRP+U1QhXgxR1+QGoM4=
sign_key = b'mark'
signature = b'Hak4Kaic0vtqTFGSlQNiIeeD6ngex74yoOExgVcXUzQ=如果我将dataToSign更改为'markmark',则它们不匹配:
C输出:
PSK is MBXjqeJm6jNEGa7TvqIEkbRHbRP+U1QhXgxR1+QGoM4=
ecodedPSK is 0␕��f�3D␙�Ӿ�␄��Gm␓�ST!^␌Q��␆��
dataToSign is markmark
encryptedSignature is ␝�8)����jLQ��␃b!��x␞Ǿ2��1�W␗S4���?���?�␕�?
encodedSignature is Hak4Kaic0vtqTFGSlQNiIeeD6ngex74yoOExgVcXUzQ=Python输出:
C:/Python38-64/python.exe d:/Git/createsastoken/generate/test.py
PSK = MBXjqeJm6jNEGa7TvqIEkbRHbRP+U1QhXgxR1+QGoM4=
sign_key = b'markmark'
signature = b'XSf//iSjx9hB6lOQe5lcYkxLGWY+g5oXM8AX0XVGIh4='如果我把dataToSign变短,这个问题也会发生,例如“joe”。
C输出:
PSK is MBXjqeJm6jNEGa7TvqIEkbRHbRP+U1QhXgxR1+QGoM4=
ecodedPSK is 0␕��f�3D␙�Ӿ�␄��Gm␓�ST!^␌Q��␆��
dataToSign is joe
encryptedSignature is ~����␕�␡
encodedSignature is fp21m4IVnH8Arfnpb1SNY3HifxunD5se9QwF/KA3z2E=Python:
& C:/Python38-64/python.exe d:/Git/createsastoken/generate/test.py
PSK = MBXjqeJm6jNEGa7TvqIEkbRHbRP+U1QhXgxR1+QGoM4=
sign_key = b'joe'
signature = b'69FWap6f/xD4JauDwia5y9fqYdq8qnSH5F7Yo5aa4FI='发布于 2021-04-29 07:16:31
大小
const char *dataToSign = "mark";将始终为4,因为它是一个指针(至少在32位系统上)。因此,它对'mark‘有效,但对'joe’和'markmark‘无效。将其声明为
const char dataToSign[] = "whatever...";然后sizeof将给出数组大小,但这将包括终止零,因此您需要减去1。
https://stackoverflow.com/questions/67308864
复制相似问题