int computeHMACSHA1Hash(const char * unhashedcstr, char * hashedcstr, const char * key, int returncode)
{
string hashed;
size_t unhashlength = strlen(unhashedcstr);
char * nonconstunhashcstr = new char[unhashlength];
strcpy_s(nonconstunhashcstr, unhashlength + 1, unhashedcstr);
unsigned char* pixels = reinterpret_cast<unsigned char*>(nonconstunhashcstr);
returncode = 0;
HMAC_CTX* context = HMAC_CTX_new();
size_t unhashedstrlength = sizeof(unhashedcstr);
if (context != NULL)
{
if (HMAC_Init_ex(context, key, strlen(key), EVP_sha1(), NULL))
{
if (HMAC_Update(context, pixels, unhashedstrlength))
{
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int lengthOfHash = 0;
if (HMAC_Final(context, hash, &lengthOfHash))
{
std::stringstream ss;
for (unsigned int i = 0; i < lengthOfHash; ++i)
{
ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
}
hashed = ss.str();
size_t outputSize = hashed.length() + 1; // +1 for null terminator
strcpy_s(hashedcstr, outputSize, hashed.c_str());
returncode = 0;
}
else
{
returncode = 7;
}
}
else
{
returncode = 6;
}
}
else
{
returncode = 5;
}
HMAC_CTX_free(context);
}
else
{
returncode = 4;
}
return returncode;
}
int main()
{
const char * unhashedcstr = "a=services&l=v1&p=open&k=SD58292829&i=20200918125249803&n=2124&t=1600404769&f={\"invoiceCode\": \"11111\",\"invoiceNo\": \"2222\",\"inTaxAmount\": \"\",\"exTaxAmount\": \"\"}";
char * hashedcstr = new char[100];
int returncode = 0;
const char * key = "SD886A11B0EE428F";
int result = computeHMACSHA1Hash(unhashedcstr, hashedcstr, key, returncode);
return 0;
}
I tried the code above to calculating the HMAC SHA1 hash value for a content, but compared the results on https://www.freeformatter.com/hmac-generator.html#before-output it looks like I didn't do the right, im not sure what wrong I have done,any helps would be apperciated it turned out the result was "d916b4c2d277319bbf18076c158f0cbcf6c3bc57", while on the website https://www.freeformatter.com/hmac-generator.html#before-output, the result was "71482b292f2b2a47b3eca6dad5e7350566d60963", even I tried useing content was "a=services&l=v1&p=open&k=SD58292829&i=20200918125249803&n=2124&t=1600404769&f={"invoiceCode": "11111","invoiceNo": "2222","inTaxAmount": "","exTaxAmount": ""}" which removed the escape characters, the results was " 09be98b6129c149e685ed57a1d19651a602cda0d", it didn't match the correct one, any wrong I did in my code, thank you so much
1条答案
按热度按时间fhity93d1#
哈希值是在
a=se
字节上计算的,a=se
是整个输入字符串的前4个字节,因此,得到的是d916b4c2d277319bbf18076c158f0cbcf6c3bc57
,而不是对应于整个字符串的09be98b6129c149e685ed57a1d19651a602cda0d
。原因是这样的:
这里,
sizeof(unhashedcstr)
是unhashedcstr
指针本身的大小(const char*
类型),不是这个unhashedcstr
指针指向的以空结尾的C样式字符串的大小。您正在编译一个32位程序,因此指针的大小是4字节。因此,unhashedstrlength
是4。要获取C样式字符串的长度,可以改为执行以下操作:
但是作为一个注解,在现代C++中,应该避免使用原始指针(例如
const char*
、char*
、unsigned char*
)、C函数(类似于strlen()
,strcpy_s()
)和手动内存管理(new
/delete
和new[]
/delete[]
)。如果可能,您应该首选使用std::string
和/或std::vector<unsigned char>
。当您需要将缓冲区地址传递给API函数时,您可以使用std::string::data()
、std::vector::data()
,或者更一般地使用std::data()
。顺便说一下,您目前的内存泄漏:你使用
new[]
动态分配缓冲区,但是你从来不释放它们(使用delete[]
)。因此,只有在程序退出后,操作系统才会释放内存。这称为 * 内存泄漏 *。