2

我想对数据使用 AES 256 位加密,它由 "MS_ENH_RSA_AES_PROV" 提供。为此,当我尝试使用 pszProviderName=TEXT("MS_ENH_RSA_AES_PROV") 作为 CryptAcquireContext 的第三个参数运行以下代码时,我得到的输出类似于错误号 80090019 .此错误代码表示“请求的提供程序不存在”。

#include <windows.h>
#include <Wincrypt.h>

#pragma comment(lib, "crypt32.lib")

void main(void) 
{ 
    // Handle for the cryptographic provider context.
    HCRYPTPROV hCryptProv;

    // The name of the container.
    LPCTSTR pszContainerName = TEXT("MyFilter_Container");

    // The name of the provider
    LPCTSTR pszProviderName = TEXT("MS_ENH_RSA_AES_PROV");

    // Begin processing. Attempt to acquire a context
    if(CryptAcquireContext(
        &hCryptProv,
        pszContainerName,
        pszProviderName,
        PROV_RSA_FULL,
        0))
    {
        _tprintf(TEXT("A crypto context acquired"));

        // Release the CSP.
        if(hCryptProv)
        {
            if(!(CryptReleaseContext(hCryptProv, 0)))
            {
                 _tprintf(TEXT("Error during CryptReleaseContext."));
            }
        }
    }
    else
    {
        _tprintf(TEXT("An error occurred in the program. \n"));
        _tprintf(TEXT("Error number %x.\n"), GetLastError());
        exit(1); 
    }
}

如果我使用 pszProviderName=TEXT("Microsoft Enhanced RSA and AES Cryptographic Provider"),它会给出错误号 0x8009001b,这意味着“dwProvType 指定的提供程序类型与找到的提供程序类型不匹配,并且此错误只能在 pszProviderName 指定时发生一个实际的 CSP 名称”。上述错误编号在 msdn 的 CryptAcquireContext 文档中指定。我不明白为什么会这样。如果此参数为 Null,则表示要使用默认 CSP,在这种情况下一切正常。我正在使用windows7。这个 CSP 不可用还是有其他原因?请有人帮忙。谢谢。

4

1 回答 1

2

I'm not sure if this is exactly what you need but by following the example on MSDN, you can make your code succeed by making two changes.

First, MSDN says that MS_ENH_RSA_AES_PROV was named differently on Windows XP and should be used with a provider type of PROV_RSA_AES rather than PROV_RSA_FULL as in your code.

Second, trap the initial error and repeat the acquire operation for the situation where you have to create a new key container.

The following is your original code adapted according to the MSDN example, and works fine on my Windows 8 system:

int _tmain(int argc, _TCHAR* argv[])
{
    // Handle for the cryptographic provider context.
    HCRYPTPROV hCryptProv;

    // The name of the container.
    LPCTSTR pszContainerName = TEXT("MyFilter_Container");

    // Begin processing. Attempt to acquire a context
    if(CryptAcquireContext(
        &hCryptProv,
        pszContainerName,
        MS_ENH_RSA_AES_PROV,
        PROV_RSA_AES,
        0))
    {
        _tprintf(TEXT("A crypto context acquired"));

        // Release the CSP.
        if(hCryptProv)
        {
            if(!(CryptReleaseContext(hCryptProv, 0)))
            {
                _tprintf(TEXT("Error during CryptReleaseContext."));
            }
        }
    }
    else
    {
        DWORD dwError = GetLastError();
        if (dwError == NTE_BAD_KEYSET)
        {
            if(CryptAcquireContext(
                &hCryptProv,
                pszContainerName,
                MS_ENH_RSA_AES_PROV,
                PROV_RSA_AES,
                CRYPT_NEWKEYSET))
            {
                _tprintf(TEXT("A crypto context acquired"));

                // Release the CSP.
                if(hCryptProv)
                {
                    if(!(CryptReleaseContext(hCryptProv, 0)))
                    {
                        _tprintf(TEXT("Error during CryptReleaseContext."));
                    }
                }
            }
            else
            {
                _tprintf(TEXT("Unable to create a new key container. \n"));
                _tprintf(TEXT("Error number %x.\n"), dwError);
                exit(1); 
            }
        }
        else
        {
            _tprintf(TEXT("An error occurred in the program. \n"));
            _tprintf(TEXT("Error number %x.\n"), dwError);
            exit(1); 
        }
    }

    return 0;
}

Once you have success, you can use CryptGetProvParam to find the provider used, which on my system gives

Microsoft Enhanced RSA and AES Cryptographic Provider

于 2013-06-30T06:58:03.077 回答