Reputation: 1121
CryptHashData (https://msdn.microsoft.com/en-us/library/windows/desktop/aa380202(v=vs.85).aspx) is consistently returning FALSE. When I call GetLastError I am returned a value of 87 which is constant ERROR_INVALID_PARAMETER. I have verified my parameters (MSDN notes said to check pointers passed in) and everything looks OK. I've put it as close to the MSDN code sample as possible.
My goal is simply to hash a password and derive a key from it.
I am running this code on Windows 10.
My code:
std::string sPassword = "123P@ssword"; //password to hash
HCRYPTHASH hHash = NULL; //password hash handle
HCRYPTPROV hHashKeyProvider = NULL; //provider to make the key derived from the hash
HCRYPTKEY hHashDerivedKey = NULL; //key derived from password hash
//get provider to the hash based password
if (!CryptAcquireContext(
&hHashKeyProvider,
0,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT
))
{
throw std::runtime_error("Could not acquire context to make key from hash");
}
//create hash object from provider
if (!CryptCreateHash(
hHashKeyProvider,
CALG_SHA1,
0,
0,
&hHash
))
{
CryptReleaseContext(hHashKeyProvider, 0);
throw std::runtime_error("Could not create hash");
}
//get hash of password
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa380202(v=vs.85).aspx
BYTE* pbPasswordBuffer = (BYTE*)sPassword.c_str();
DWORD dwPasswordBufferLength = strlen((char*)pbPasswordBuffer);
if (!CryptHashData(
hHashKeyProvider,
pbPasswordBuffer,
dwPasswordBufferLength,
0
))
{
CryptReleaseContext(hHashKeyProvider, 0);
DWORD dwLast = GetLastError(); //THIS EQUALS 87 for ERROR_INVALID_PARAMETER WHY???
throw std::runtime_error("Could not hash password");
}
//create key from hash
if (!CryptDeriveKey(
hHashKeyProvider,
CALG_AES_256,
hHash,
0,
&hHashDerivedKey
))
{
CryptDestroyHash(hHash);
CryptReleaseContext(hHashKeyProvider, 0);
throw std::runtime_error("Could not create key from password hash");
}
//free the hash
CryptDestroyHash(hHash);
Suggestions?
Upvotes: 1
Views: 372
Reputation: 2978
Watch out, you've accidentally passed hHashKeyProvider
instead of hHash
into CryptHashData()
.
In addition, your GetLastError()
call should come before CryptReleaseContext()
, otherwise an error in the latter might seem like it came from CryptHashData()
instead.
Upvotes: 2
Reputation: 88007
if (!CryptHashData(
hHashKeyProvider,
should be
if (!CryptHashData(
hHash,
Upvotes: 2