In C++ (C++11 to be precise), I would like to get the HMAC SHA512 hash of a string containing the NUL character (the ASCII character that has all eight of its bits set to 0).
Using crypto++, so far my approach has been as follows:
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;
This doesn't work properly when a NUL character is included as in the message
string above.
The base64 encoded version of the hash (variable mac
) I get is
bXmQCkzhzq3J81vInF6IRtxXyd+mN8TRh8e3qHThJ+/RYVcgRkFZ9iStKnNaVsGgco/nisUeRpT3m388UR/BMg==
instead of the expected
hUk4PX3mnqs943JnMR+ptW6f8+enIUGBd4x7sUA+Ug2squOFVF6ZdiCewSBDlGAwNuWf+9Uh0AqUkQV1vMNHxg==
EDIT
The expected output can be obtained from the Bash command line as follows:
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'
This generates the expected output as given above.