C++ 使用 openssl 实现 HMAC-SHA256



我正在尝试使用 HMAC-SHA256 在 C++ 中使用 openssl。

我正在使用 python 代码仔细检查我的输出,这似乎证明出了问题......令人惊讶的是,我能够使用 HMAC-SHA384 和 HMAC-SHA512 进行哈希处理(仍然用我的 python 代码仔细检查)

有人可以指出我做错了什么吗?

我的代码 :

static std::vector<unsigned char> hmac_sha256(const std::vector<unsigned char>& data, const std::vector<unsigned char>& key)
{
    unsigned int len = EVP_MAX_MD_SIZE;
    std::vector<unsigned char> digest(len);
    HMAC_CTX ctx;
    HMAC_CTX_init(&ctx);
    HMAC_Init_ex(&ctx, key.data(), key.size(), EVP_sha256(), NULL);
    HMAC_Update(&ctx, data.data(), data.size());
    HMAC_Final(&ctx, digest.data(), &len);
    HMAC_CTX_cleanup(&ctx);
    return digest;
}

我对 HMAC-SHA384 和 HMAC-SHA512 的实现与上述实现的区别仅在于分别将 EVP_sha256() 更改为 EVP_sha384() 和 EVP_sha512()...

示例 : message = "azertyAZERTY", key = "vzxgPuegSjRksLnCAu/LElxWRonjVkCoArWzZqliiSEtmlbaCfZaGkrSweWJKQkgQsyrBUpSusAcPcGDfFhWOx==" (在我的函数中使用之前应该对 b64 进行解码)。

以下 python 实现

import json, hmac, hashlib, time, requests, base64 from requests.auth import AuthBase
message = "azertyAZERTY"
hmac_key = base64.b64decode("vzxgPuegSjRksLnCAu/LElxWRonjVkCoArWzZqliiSEtmlbaCfZaGkrSweWJKQkgQsyrBUpSusAcPcGDfFhWOx==")
signature256 = hmac.new(hmac_key, message, hashlib.sha256)
print('signature 256 : ' + 
signature256.digest().encode('base64').rstrip('n'))
signature384 = hmac.new(hmac_key, message, hashlib.sha384)
print('signature 384 : ' + 
signature384.digest().encode('base64').rstrip('n'))
signature512 = hmac.new(hmac_key, message, hashlib.sha512)
print('signature 512 : ' + 
signature512.digest().encode('base64').rstrip('n'))

返回

signature 256 : tfnYBB630T/8TemIeNMSSTuY12eJMmel55ZWaRAEq/w=
signature 384 : irWXsFWoNREZddkTRDzPFgyhyiLoIt8uoi0Kpxw4GgYSfSnILXLdQu0HuM5qN4Zb
signature 512 : DU+sAkJnJBqY1QPwJRmwCK/vdACwKfysz+PetdsmvlmgRlK8Ad1tbHsjvRs/By2PR7uWEngXGjocTgqjDGMTFw==

而我的 C++ 实现

std::string secret = "vzxgPuegSjRksLnCAu/LElxWRonjVkCoArWzZqliiSEtmlbaCfZaGkrSweWJKQkgQsyrBUpSusAcPcGDfFhWOx==";
std::vector<unsigned char> v = b64_decode(secret);
std::string message = "azertyAZERTY";
std::vector<unsigned char> data(message.begin(), message.end());
std::vector<unsigned char> v = b64_decode(secret);
std::cout << "signature 256 : " << b64_encode(hmac_sha256(data, v)) << std::endl;
std::cout << "signature 384 : " << b64_encode(hmac_sha384(data, v)) << std::endl;
std::cout << "signature 512 : " << b64_encode(hmac_sha512(data, v)) << std::endl;

返回

signature 256 : AUTcxQUgWHDOX3KzXJwl6ACDtfNJlMXq55pTBGp3RxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
signature 384 : irWXsFWoNREZddkTRDzPFgyhyiLoIt8uoi0Kpxw4GgYSfSnILXLdQu0HuM5qN4ZbAAAAAAAAAAAAAAAAAAAAAA==
signature 512 : DU+sAkJnJBqY1QPwJRmwCK/vdACwKfysz+PetdsmvlmgRlK8Ad1tbHsjvRs/By2PR7uWEngXGjocTgqjDGMTFw==

人们可以看到签名 256 看起来非常不同......

提前非常感谢!

我在为

我正在开发的遗留软件寻找类似的解决方案时遇到了这个问题。

在 sha256 和 sha384 的输出端看到的额外A是由于 len 被定义为值为 64 的 EVP_MAX_MD_SIZE,并且是 sha512 预期的最大长度。将 len 更改为 32(对于 sha256)可修复 OP 报告的问题。

最新更新