C++ 和 PHP 中的不同结果 HMAC SHA-256
Different result HMAC SHA-256 in C++ and PHP
我将字符串编码为 base64 并使用此 base64 字符串生成 HMAC SHA256。我将 HMAC(char bytes) 的结果编码为 base64。
我使用 C++:openssl 库。
并且在 PHP 和 C++ 中得到了不同的结果:
C++:
JSON: {"req_hash":"someUniqCodeHash","answer":true}
BASE64: eyJyZXFfaGFzaCI6InNvbWVVbmlxQ29kZUhhc2giLCJhbnN3ZXIiOnRydWV9
HMAC: P/p2YlxL8xdhmn+QIAlVLFDS50ai4JE/l1pMMrKZKrE=
PHP:
JSON: {"req_hash":"someUniqCodeHash","answer":true}
BASE64: eyJyZXFfaGFzaCI6InNvbWVVbmlxQ29kZUhhc2giLCJhbnN3ZXIiOnRydWV9
HMAC: P/p2YlxL8xdhmn+QIAlVLFDS50ai4JE/l1pMMrKZKrE=
如果你能看到,HMAC 结果相同!
c++: P/p2YlxL8xdhmn+QIAlVLFDS50ai4JE/l1pMMrKZKrE=
php: P/p2YlxL8xdhmn+QIAlVLFDS50ai4JE/l1pMMrKZKrE=
但是,当我像这样更改 JSON 时(将 true
更改为 false
):
JSON: {"req_hash":"someUniqCodeHash","answer":false}
我明白了:
C++:
JSON: {"req_hash":"someUniqCodeHash","answer":false}
BASE64: eyJyZXFfaGFzaCI6InNvbWVVbmlxQ29kZUhhc2giLCJhbnN3ZXIiOmZhbHNlfQ==
HMAC: znUOWS2MMLpjIBSpq2GfSNivaL8IUDcZXZs24D0=
PHP:
JSON: {"req_hash":"someUniqCodeHash","answer":false}
BASE64: eyJyZXFfaGFzaCI6InNvbWVVbmlxQ29kZUhhc2giLCJhbnN3ZXIiOmZhbHNlfQ==
HMAC: znUOWS2MMLpjIBSpq2GfSNivaL8IUDcZXZs24D0AHZA=
为什么HMAC结果不一样?
可以看到:
C++: znUOWS2MMLpjIBSpq2GfSNivaL8IUDcZXZs24D0=
PHP: znUOWS2MMLpjIBSpq2GfSNivaL8IUDcZXZs24D0AHZA=
在PHP HMAC 字符串中添加了一些字符:...AHZA=
。
这是什么?
还有我的PHP代码:
<?php
$b = base64_encode('{"req_hash":"someUniqCodeHash","answer":false}');
$hmac =$b.".".base64_encode(hash_hmac('sha256',$b,'eyJhZGRyZXNzX3RvIjp7JzEnOidjbGll',true));
我的C++代码:
std::string sfjson = "{\"req_hash\":\"someUniqCodeHash\",\"answer\":false}";
std::cout << "JSON: " << sfjson << "\n";
std::string fencoded_data = base64_encode_str(sfjson);
std::cout << "BASE64: " << fencoded_data << "\n";
unsigned char* digest;
std::string key = "eyJhZGRyZXNzX3RvIjp7JzEnOidjbGll";
digest = HMAC(EVP_sha256(), reinterpret_cast<const unsigned char*>(key.c_str()), key.length(), reinterpret_cast<const unsigned char*>(fencoded_data.c_str()), fencoded_data.length(), NULL, NULL);
std::string sName(reinterpret_cast<char*>(digest));
std::string hmac_data = base64_encode_str(sName);
std::cout << "HMAC: " << hmac_data << "\n";
Base64 从那里:https://gist.github.com/rustem-art/5f6b510c65bbbfd279386225b978f960
我找到了解决办法! ;)
切勿将 NULL 用作:
digest = HMAC(EVP_sha256(),
reinterpret_cast<const unsigned char*>(key.c_str()), key.length(),
reinterpret_cast<const unsigned char*>(data.c_str()), data.length(),
NULL, NULL);
为 return 函数使用特殊变量(在我的代码中是:diglen 和 result)。
unsigned int diglen;
unsigned char result[EVP_MAX_MD_SIZE];
digest = HMAC(EVP_sha256(),
reinterpret_cast<const unsigned char*>(key.c_str()), key.length(),
reinterpret_cast<const unsigned char*>(data.c_str()), data.length(),
result, &diglen);
我将字符串编码为 base64 并使用此 base64 字符串生成 HMAC SHA256。我将 HMAC(char bytes) 的结果编码为 base64。
我使用 C++:openssl 库。
并且在 PHP 和 C++ 中得到了不同的结果:
C++:
JSON: {"req_hash":"someUniqCodeHash","answer":true}
BASE64: eyJyZXFfaGFzaCI6InNvbWVVbmlxQ29kZUhhc2giLCJhbnN3ZXIiOnRydWV9
HMAC: P/p2YlxL8xdhmn+QIAlVLFDS50ai4JE/l1pMMrKZKrE=
PHP:
JSON: {"req_hash":"someUniqCodeHash","answer":true}
BASE64: eyJyZXFfaGFzaCI6InNvbWVVbmlxQ29kZUhhc2giLCJhbnN3ZXIiOnRydWV9
HMAC: P/p2YlxL8xdhmn+QIAlVLFDS50ai4JE/l1pMMrKZKrE=
如果你能看到,HMAC 结果相同!
c++: P/p2YlxL8xdhmn+QIAlVLFDS50ai4JE/l1pMMrKZKrE=
php: P/p2YlxL8xdhmn+QIAlVLFDS50ai4JE/l1pMMrKZKrE=
但是,当我像这样更改 JSON 时(将 true
更改为 false
):
JSON: {"req_hash":"someUniqCodeHash","answer":false}
我明白了:
C++:
JSON: {"req_hash":"someUniqCodeHash","answer":false}
BASE64: eyJyZXFfaGFzaCI6InNvbWVVbmlxQ29kZUhhc2giLCJhbnN3ZXIiOmZhbHNlfQ==
HMAC: znUOWS2MMLpjIBSpq2GfSNivaL8IUDcZXZs24D0=
PHP:
JSON: {"req_hash":"someUniqCodeHash","answer":false}
BASE64: eyJyZXFfaGFzaCI6InNvbWVVbmlxQ29kZUhhc2giLCJhbnN3ZXIiOmZhbHNlfQ==
HMAC: znUOWS2MMLpjIBSpq2GfSNivaL8IUDcZXZs24D0AHZA=
为什么HMAC结果不一样?
可以看到:
C++: znUOWS2MMLpjIBSpq2GfSNivaL8IUDcZXZs24D0=
PHP: znUOWS2MMLpjIBSpq2GfSNivaL8IUDcZXZs24D0AHZA=
在PHP HMAC 字符串中添加了一些字符:...AHZA=
。
这是什么?
还有我的PHP代码:
<?php
$b = base64_encode('{"req_hash":"someUniqCodeHash","answer":false}');
$hmac =$b.".".base64_encode(hash_hmac('sha256',$b,'eyJhZGRyZXNzX3RvIjp7JzEnOidjbGll',true));
我的C++代码:
std::string sfjson = "{\"req_hash\":\"someUniqCodeHash\",\"answer\":false}";
std::cout << "JSON: " << sfjson << "\n";
std::string fencoded_data = base64_encode_str(sfjson);
std::cout << "BASE64: " << fencoded_data << "\n";
unsigned char* digest;
std::string key = "eyJhZGRyZXNzX3RvIjp7JzEnOidjbGll";
digest = HMAC(EVP_sha256(), reinterpret_cast<const unsigned char*>(key.c_str()), key.length(), reinterpret_cast<const unsigned char*>(fencoded_data.c_str()), fencoded_data.length(), NULL, NULL);
std::string sName(reinterpret_cast<char*>(digest));
std::string hmac_data = base64_encode_str(sName);
std::cout << "HMAC: " << hmac_data << "\n";
Base64 从那里:https://gist.github.com/rustem-art/5f6b510c65bbbfd279386225b978f960
我找到了解决办法! ;)
切勿将 NULL 用作:
digest = HMAC(EVP_sha256(),
reinterpret_cast<const unsigned char*>(key.c_str()), key.length(),
reinterpret_cast<const unsigned char*>(data.c_str()), data.length(),
NULL, NULL);
为 return 函数使用特殊变量(在我的代码中是:diglen 和 result)。
unsigned int diglen;
unsigned char result[EVP_MAX_MD_SIZE];
digest = HMAC(EVP_sha256(),
reinterpret_cast<const unsigned char*>(key.c_str()), key.length(),
reinterpret_cast<const unsigned char*>(data.c_str()), data.length(),
result, &diglen);