在C++11中使用Crypto++计算含NUL字符字符串的HMAC SHA512哈希
计算包含NUL字符的字符串的HMAC-SHA512(Crypto++实现)
没问题,我帮你补全并优化这个Crypto的实现,确保能正确处理包含NUL字符的消息——这部分很关键,因为C默认的字符串处理很容易在NUL字符处截断数据。
完整可运行代码
#include <iostream> #include <string> #include "cryptopp/hmac.h" #include "cryptopp/sha.h" #include "cryptopp/base64.h" #include "cryptopp/filters.h" #include "cryptopp/hex.h" int main() { // 初始化带NUL的消息:"My\0Message",总长度是2(My) + 1(\0) +7(Message) = 10 std::string message("My\0Message", 10); // Base64编码的密钥(如果你的密钥是明文,直接跳过解码步骤即可) std::string key_base64 = "MYSECRETKEY"; std::string key; // 解码Base64密钥到原始字节流 try { CryptoPP::StringSource ss(key_base64, true, new CryptoPP::Base64Decoder( new CryptoPP::StringSink(key) ) ); } catch (const CryptoPP::Exception& e) { std::cerr << "Base64解码失败: " << e.what() << std::endl; return 1; } std::string mac; // 初始化HMAC-SHA512对象,传入密钥的原始字节和长度 CryptoPP::HMAC<CryptoPP::SHA512> hmac(reinterpret_cast<const byte*>(key.data()), key.size()); // 处理消息:直接传入std::string对象,确保所有字节(包括NUL)都被处理 CryptoPP::StringSource ss(message, true, new CryptoPP::HashFilter(hmac, new CryptoPP::StringSink(mac) ) ); // 可选:将二进制哈希结果编码为十六进制字符串,方便查看和传输 std::string encoded_mac; CryptoPP::StringSource ss_mac(mac, true, new CryptoPP::HexEncoder( new CryptoPP::StringSink(encoded_mac), false // 设为true输出大写,false输出小写 ) ); std::cout << "HMAC-SHA512结果(十六进制):" << encoded_mac << std::endl; return 0; }
关键注意点
- 带NUL的字符串初始化:你已经用了
std::string("My\0Message", 10)的构造方式,这完全正确——千万不能用默认的std::string("My\0Message"),它会在第一个NUL字符处截断,只保留"My"。 - 密钥处理:如果你的密钥不是Base64编码的,直接删除Base64解码部分,用明文密钥初始化HMAC即可。
- 避免NUL截断:处理消息时,一定要直接传入
std::string对象给StringSource,绝对不要用message.c_str()——后者会返回以NUL结尾的指针,导致NUL之后的内容被丢弃。StringSource会自动读取整个字符串的所有字节,包括NUL。 - 异常捕获:CryptoPP的操作可能抛出异常(比如无效的Base64编码),加上异常处理能让程序更健壮。
编译指令(Linux环境)
编译时需要链接Crypto++库:
g++ -o hmac_sha512 hmac_sha512.cpp -lcryptopp
内容的提问来源于stack exchange,提问作者John S.
相关产品推荐
相关产品推荐

