使用crypto ++在C ++中散列包含NUL字符的字符串

时间:2018-03-25 15:30:18

标签: c++ string hash crypto++ nul

在C ++中(准确地说是C ++ 11),我想获得包含NUL字符的字符串的HMAC SHA512哈希值(将其所有八位设置为0的ASCII字符)。

使用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;

如果在上面的message字符串中包含NUL字符,则无效。

我得到的hash64(变量mac)的base64编码版本是

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'

这会产生上面给出的预期输出。

1 个答案:

答案 0 :(得分:0)

  

如果在上面的消息字符串中包含NUL字符,则无法正常工作。

您使用的构造函数应该没问题,因为机制使用std::string::size()而不是std::string::c_str()来确定长度。我怀疑其他东西不太正确,就像字符编码问题一样。

您正在使用std::string的{​​{1}}构造函数。 StringSource的第二个构造函数采用二进制字符串。您可能在生产代码中有更好的运气:

StringSource

另请参阅Crypto ++ wiki上的StringSource