Странное поведение Win32 MD5 hasher

Я использую эту функцию для генерации хеша строки

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;

}

Но у меня есть проблема. Некоторые пользователи скомпилированного двоичного файла не могут генерировать md5. Тем не менее, я вставляю между строк:

cout << "randomstring:gfdgfdgfdgfdg" << endl;

И теперь все работает для тех пользователей, но не работает для некоторых других. Что за черт?

0

Решение

4-й параметр CryptGetHashParam, pdwDataLen, имеет две функции. При входе он указывает длину доступного буфера. При выходе он содержит длину реально используемых данных. Это довольно распространенная концепция в Windows API.

Потому что вы не инициализируете dwHashLen с любым значением, все, что в данный момент находится в стеке, передается функции. Если он меньше размера хеш-значения, он не работает и функция возвращает ошибку. Если это случается больше, это работает. Выполнение какой-либо другой несвязанной операции может изменить стек случайным образом, поэтому иногда заставляйте его работать.

Поэтому решение состоит в том, чтобы инициализировать размер следующим образом:

DWORD dwHashLen = sizeof(BytesHash);

Вы можете проверить GetLastError() в следующий раз, когда что-то подобное произойдет, он подскажет нам, что пошло не так (ERROR_MORE_DATA).

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]