【发布时间】:2018-09-03 18:36:00
【问题描述】:
在 C++(准确地说是 C++11)中,我想获取包含 NUL 字符(所有八位都设置为 0 的 ASCII 字符)的字符串的 HMAC SHA512 哈希。
使用crypto++,到目前为止我的方法如下:
std::string message("My\0Message",2+1+7);
std::string key_base64 = "MYSECRETKEY";
std::string key;
StringSource ss(key_base64, true, new Base64Decoder(new StringSink(key)));
std::string mac, encoded;
HMAC< SHA512 > hmac((byte*)key.c_str(), key.length());
StringSource(message,
true,
new HashFilter(hmac, new StringSink(mac))
); // StringSource
encoded.clear();
StringSource(mac,
true,
new Base64Encoder(new StringSink(encoded), false) // Base64Encoder. Pass argument 'false' to prevent insertion of line breaks
); // StringSource
std::cout << "Hashed message (Base64): " << encoded << std::endl;
当 NUL 字符包含在上面的 message 字符串中时,这将无法正常工作。
我得到的哈希的base64编码版本(变量mac)是
bXmQCkzhzq3J81vInF6IRtxXyd+mN8TRh8e3qHThJ+/RYVcgRkFZ9iStKnNaVsGgco/nisUeRpT3m388UR/BMg==
而不是预期的
hUk4PX3mnqs943JnMR+ptW6f8+enIUGBd4x7sUA+Ug2squOFVF6ZdiCewSBDlGAwNuWf+9Uh0AqUkQV1vMNHxg==
编辑
可以从 Bash 命令行获得预期的输出,如下所示:
hex_encoded_secret=$(echo -n "MYSECRETKEY" | base64 --decode | xxd -p | tr '\n' ' ' | tr -d '[:space:]')
echo -ne "My\0Message" | openssl dgst -sha512 -mac HMAC -macopt hexkey:"${hex_encoded_secret}" -binary | base64 | tr -d '\n'
这会生成上面给出的预期输出。
【问题讨论】:
-
如何确定期望值?没有嵌入空值的字符串是否有效?
-
没有嵌入 NUL 的字符串可以工作。可以从命令行获得预期的输出,如我上面原始问题的编辑所示。
-
请发布一个 MCVE,包括完整的 C++ 代码和你真正的 bash 比较脚本。
echo -n "MY_SECRET_KEY" | base64 --decode不可能工作。 -
您可能应该删除 OpenSSL 装置中的大部分命令。使用
echo -e将完全相同的二进制字符串发送到 OpenSSL。开始对您的 OpenSSL 相关命令进行故障排除。 -
@jww:您在下面建议的编码确实存在问题。密钥 base64 字符串在末尾需要一个额外的 = 以使其成为 4 个字符的倍数。没有,不同的工具似乎对此进行了不同的解码。我现在设法让它工作,感谢您的帮助和在线 HMAC 生成器的链接
标签: c++ string hash crypto++ nul