I wrote some code using the Microsoft CryptoAPI to calculate a SHA-1 and got the compiled exe working on Windows 7, Win Server 2008, Win Server 2003. However, when I run it under Windows XP SP3, it does not work.
I narrowed down the failure to the CryptAcquireContext()
call.
I did notice that a previous post talked about the XP faulty naming of "… (Prototype)" and it must be accounted for by using a WinXP specific macro MS_ENH_RSA_AES_PROV_XP.
I did the XP specific code modifications and it still doesn't work. (The bResult
returns 0 false on Win XP, all other platforms bResult
returns 1 true.)
I checked the MS_ENH_RSA_AES_PROV_XP with the actual key+string values I see in regedit.exe so everything looks like it's set up to work but no success.
Have I overlooked something to make it work on Windows XP?
I've pasted shortest possible example to illustrate the issue. I used VS2010 C++.
// based on examples from http://msdn.microsoft.com/en-us/library/ms867086.aspx
#include "windows.h"
#include "wincrypt.h"
#include <iostream>
#include <iomanip> // for setw()
void main()
{
BOOL bResult;
HCRYPTPROV hProv;
// Attempt to acquire a handle to the default key container.
bResult = CryptAcquireContext(
&hProv, // Variable to hold returned handle.
NULL, // Use default key container.
MS_DEF_PROV, // Use default CSP.
PROV_RSA_FULL, // Type of provider to acquire.
0); // No special action.
std::cout << "line: " << std::setw(4) << __LINE__ << "; " << "bResult = " << bResult << std::endl;
if (! bResult) { // try Windows XP provider name
bResult = CryptAcquireContext(
&hProv, // Variable to hold returned handle.
NULL, // Use default key container.
MS_ENH_RSA_AES_PROV_XP, // Windows XP specific instead of using default CSP.
PROV_RSA_AES, // Type of provider to acquire.
0); // No special action.
std::cout << "line: " << std::setw(4) << __LINE__ << "; " << "bResult = " << bResult << std::endl;
}
if (bResult)
CryptReleaseContext(hProv, 0);
}
Windows 7 success:
Windows XP failure:
In your CryptAcquireContext code, it appears you are missing the parameter to get a context without a specific container set. You need to pass the CRYPT_VERIFYCONTEXT option in CryptAcquireContext.
Windows 7 might be working around this.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa379886(v=vs.85).aspx
For further diagnosis, the results of GetLastError() would be requisite.
来源:https://stackoverflow.com/questions/9794745/ms-cryptoapi-doesnt-work-on-windows-xp-with-cryptacquirecontext