c# - 与 .NET 相比,OpenSSL HMACSHA256 产生不同的结果
问题描述
我正在使用C#
和C++
withOpenSSL
来计算HMACSHA256
has with a key 并且都产生不同的结果。我究竟做错了什么?
C#
代码:
public static string CreateSignature(string signingString, string sharedKey)
{
var key = Encoding.ASCII.GetBytes(sharedKey);
var hmac = new HMACSHA256(key);
var data = Encoding.ASCII.GetBytes(signingString);
var hash = hmac.ComputeHash(data);
return Convert.ToBase64String(hash);
}
C++
代码:
std::string SignatureProvider::getSignature(std::string stringToSign, std::string key)
{
const char* pKey = key.c_str();
const char* pData = stringToSign.c_str();
unsigned char* result = nullptr;
unsigned int len = 32;
result = (unsigned char*)malloc(sizeof(char) * len);
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, pKey, strlen(pKey), EVP_sha256(), NULL);
HMAC_Update(&ctx, (unsigned char*)&pData, strlen(pData));
HMAC_Final(&ctx, result, &len);
HMAC_CTX_cleanup(&ctx);
return base64_encode(result, len);
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len)
{
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i <4); i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for (j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while ((i++ < 3))
ret += '=';
}
return ret;
}
我只是base64
为了完整性而包含了转换,但在它之前已经不同了。
解决方案
为什么不使用 HMAC 函数本身?我已尝试使用此代码,C++ 和 C# 代码都导致相同的 HMAC:
std::string getSignature(std::string stringToSign, std::string key)
{
const char* pKey = key.c_str();
const char* pData = stringToSign.c_str();
unsigned char* result = nullptr;
unsigned int len = 32;
result = (unsigned char*)malloc(sizeof(char) * len);
int nkeyLen = strlen(pKey);
int dataLen = strlen(pData);
result = HMAC(EVP_sha256(), pKey, nkeyLen, (unsigned char*)pData, dataLen, NULL, NULL);
return base64_encode(result, len);
}
推荐阅读
- php - 用 PHP 结构的子元素替换 DOM 结构的 innerHTML 和 HTML 之后
- python-3.x - Discord.py Python 经济机器人,带有 mongodb“NoneType”错误
- javascript - 在 contenteditable="true" 上键入时更改特定单词的颜色
- python - python - 如何在TRUE或FALSE中的python webscraping期间转换复选框TICK或CROSS?
- android - 如何在 java-library 中包含 Room 持久性库?
- termux - Termux 存储库正在维护或关闭
- discord.js - 类型错误:client.execute 不是函数
- node.js - 使用 fpcalc 生成原始未压缩指纹期间出现 ERR_OUT_OF_RANGE 错误
- angular - 将 grpc 一元调用转换为承诺
- material-ui - Material-UI Table/XGrid - 如何为每个单元格设置不同的颜色