我使用此函数生成字符串的哈希
std::string MD5(string input)
{
BYTE BytesHash[33];//!
DWORD dwHashLen;
string final;
HCRYPTPROV CryptProv;
HCRYPTHASH CryptHash;
if (CryptAcquireContext(&CryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) {
if (CryptCreateHash(CryptProv, CALG_MD5, 0, 0, &CryptHash)) {
if (CryptHashData(CryptHash, (BYTE*)input.c_str(), input.length(), 0)) {
if (CryptGetHashParam(CryptHash, HP_HASHVAL, BytesHash, &dwHashLen, 0)) {
final.clear();
string hexcharset = "0123456789ABCDEF";
for (int j = 0; j < 16; j++) {
final += hexcharset.substr(((BytesHash[j] >> 4) & 0xF), 1);
final += hexcharset.substr(((BytesHash[j]) & 0x0F), 1);
}
}
}
}
} CryptDestroyHash(CryptHash);
CryptReleaseContext(CryptProv, 0);
return final;
}
Run Code Online (Sandbox Code Playgroud)
但是我有一个问题。某些已编译二进制文件的用户无法生成md5。但是,我在某些行之间插入:
cout << "randomstring:gfdgfdgfdgfdg" << endl;
Run Code Online (Sandbox Code Playgroud)
现在,一切对于这些用户都有效,但不适用于其他用户。我勒个去?
第四届参数CryptGetHashParam,pdwDataLen有两个功能。输入后,它指定可用缓冲区的长度。退出时,它包含实际使用的数据的长度。这是Windows API中相当普遍的概念。
因为您不dwHashLen使用任何值初始化,所以堆栈上当前存在的任何内容都将传递给该函数。如果它小于哈希值的大小,则它将不起作用,并且该函数将返回错误。如果碰巧更大,它将起作用。进行其他一些不相关的操作可能会以随机方式更改堆栈,因此有时会使其工作。
因此,解决方案是像这样初始化大小:
DWORD dwHashLen = sizeof(BytesHash);
Run Code Online (Sandbox Code Playgroud)
GetLastError()下次您可能想检查类似的事情,它会告诉您发生了什么问题(ERROR_MORE_DATA)。
| 归档时间: |
|
| 查看次数: |
111 次 |
| 最近记录: |