CryptAcquireContext using MS_ENHANCED_PROV
Hi,
I am facing one problem when decrypting the password using
MS_ENHANCED_PROV. I have the following code:
HRESULT DecryptString(BSTR bstrToDecrypt, LPCTSTR pszSecret, BSTR
*pbstrDecrypted)
{
HCRYPTPROV hCryptProv;
HCRYPTKEY hCryptKey;
BYTE baKeyRandom[10] = {87,194, 253,4,98,23,192,102,176,37};
HCRYPTHASH hSaveHash;
USES_CONVERSION;
HRESULT hr;
hCryptProv = NULL;
hCryptKey = NULL;
hSaveHash = NULL;
try {
BOOL bSuccess;
// Attempt to acquire a context and a key container. The context
will use the default CSP (cryptographic service provider)
// for the RSA_FULL provider type.
bSuccess = ::CryptAcquireContext(&hCryptProv, // handle to the CSP
CRYPTCONTEXT, // use default key container(CRYPTCONTEXT)
//MS_DEF_PROV,
MS_ENHANCED_PROV, // use the Enhanced Cryptographic
Provider (128 bit)
PROV_RSA_FULL, // provider type
CRYPT_MACHINE_KEYSET);// flag values, No special
action(CRYPT_MACHINE_KEYSET)
// Derive a symmetric key from a hash object by performing the
// following steps:
// 1. Call CryptCreateHash to retrieve a handle to a hash object.
// 2. Call CryptHashData to add a text string (password) to the
// hash object.
// 3. Call CryptDeriveKey to create the symmetric key from the
// hashed password derived in step 2.
// You will use the key later to create an HMAC hash object.
FAILED_LAST(::CryptCreateHash(hCryptProv, ALG_CLASS_HASH|
ALG_TYPE_ANY|ALG_SID_MD5, 0, 0, &hSaveHash));
// Hash the random stream
FAILED_LAST(::CryptHashData(hSaveHash, baKeyRandom,
sizeof(baKeyRandom), 0) );
// Hash the data
FAILED_LAST(::CryptHashData(hSaveHash, (LPBYTE)T2CW(pszSecret),
_tcslen(pszSecret) * sizeof(WCHAR), 0));
// Create a session key based on the hash of the password
FAILED_LAST(::CryptDeriveKey(hCryptProv, CALG_RC4, hSaveHash, 0,
&hCryptKey) );
// Now Encrypt the value
DWORD dwSize;
LPBYTE pbTemp;
dwSize = ::SysStringByteLen(bstrToDecrypt);
if (dwSize)
{
pbTemp = new BYTE[dwSize+2];
memset(pbTemp, 0, dwSize+2);
memcpy((LPWSTR)pbTemp, bstrToDecrypt, dwSize);
bSuccess = ::CryptDecrypt(hCryptKey, NULL, TRUE, 0, pbTemp,
&dwSize);
if (!bSuccess)
{
delete [] pbTemp;
FAILED_LAST(bSuccess);
}
*pbstrDecrypted = ::SysAllocStringByteLen((LPCSTR)pbTemp, dwSize);
delete [] pbTemp;
}
else
{
*pbstrDecrypted = ::SysAllocString(NULL);
}
hr = S_OK;
}
catch (HRESULT hrCatch)
{
ATRACE(ATRACE_CATEGORY_ERROR, _T("CBasicCrypto::DecryptString Failed
to decrypt the string - %d.\n"), GetLastError());
hr = hrCatch;
}
if (hSaveHash)
::CryptDestroyHash(hSaveHash);
if (hCryptKey)
::CryptDestroyKey(hCryptKey);
if (hCryptProv)
::CryptReleaseContext(hCryptProv, 0);
return hr;
}
Now, when the CryptAcquireContext is called with MS_DEF_PROV (which is
commented in the above code), I get correct value of my password and
if it is called with MS_ENHANCED_PROV, then it returns some garbage
values "?????????". Do I need to change ALG_ID anywhere in the code
while creating the hashkey or deriving the key? Is this code
correct?/?
Please let me know.
Thanks in adv,
PI