Microsoft's cryptoAPI "Microsoft Enhanced RSA and AES Cryptographic Provider" selection doesn't working on win7

2

I want to use AES 256 bit enncrytion for data and it is provided by "MS_ENH_RSA_AES_PROV" .For that When I tried running below code with pszProviderName=TEXT("MS_ENH_RSA_AES_PROV") as 3rd parameter of CryptAcquireContext, I get output something like Error number 80090019 .This error code means "The requested provider does not exist".

#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); 
    }
}

And if I use pszProviderName=TEXT("Microsoft Enhanced RSA and AES Cryptographic Provider"), it gives Error number 0x8009001b which means "The provider type specified by dwProvType does not match the provider type found and that this error can only occur when pszProviderName specifies an actual CSP name".Above error numbers are specified in CryptAcquireContext documentation at msdn. I am not getting why this is happening. If this parameter is Null that means default CSP to use, in that case everything works fine. I am using windows7. Is this CSP not available or some other reason is there?Please somebody help.Thanks in adv.

visual-c++
encryption
aes
cryptoapi
mscapi
asked on Stack Overflow Jun 29, 2013 by chammu • edited Jun 9, 2015 by jww

1 Answer

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

answered on Stack Overflow Jun 30, 2013 by Roger Rowland • edited Jun 30, 2013 by Roger Rowland

User contributions licensed under CC BY-SA 3.0