- Article
ImportantThis API is deprecated. New and existing software should start using Cryptography Next Generation APIs. Microsoft may remove this API in future releases.
The CryptAcquireContext function is used to acquire a handle to a particular key container within a particular cryptographic service provider (CSP). This returned handle is used in calls to CryptoAPI functions that use the selected CSP.
This function first attempts to find a CSP with the characteristics described in the dwProvType and pszProvider parameters. If the CSP is found, the function attempts to find a key container within the CSP that matches the name specified by the pszContainer parameter. To acquire the context and the key container of a private key associated with the public key of a certificate, useCryptAcquireCertificatePrivateKey.
With the appropriate setting of dwFlags, this function can also create and destroy key containers and can provide access to a CSP with a temporary key container if access to a private key is not required.
Syntax
BOOL CryptAcquireContextA( [out] HCRYPTPROV *phProv, [in] LPCSTR szContainer, [in] LPCSTR szProvider, [in] DWORD dwProvType, [in] DWORD dwFlags);
Parameters
[out] phProv
A pointer to a handle of a CSP. When you have finished using the CSP, release the handle by calling the CryptReleaseContext function.
[in] szContainer
The key container name. This is a null-terminated string that identifies the key container to the CSP. This name is independent of the method used to store the keys. Some CSPs store their key containers internally (in hardware), some use the system registry, and others use the file system. In most cases, when dwFlags is set to CRYPT_VERIFYCONTEXT, pszContainer must be set to NULL. However, for hardware-based CSPs, such as a smart card CSP, can be access publicly available information in the specfied container.
For more information about the usage of the pszContainer parameter, see Remarks.
[in] szProvider
A null-terminated string that contains the name of the CSP to be used.
If this parameter is NULL, the user default provider is used. For more information, seeCryptographic Service Provider Contexts. For a list of available cryptographic providers, seeCryptographic Provider Names.
An application can obtain the name of the CSP in use by using the CryptGetProvParam function to read the PP_NAME CSP value in the dwParam parameter.
The default CSP can change between operating system releases. To ensure interoperability on different operating system platforms, the CSP should be explicitly set by using this parameter instead of using the default CSP.
[in] dwProvType
Specifies the type of provider to acquire. Defined provider types are discussed inCryptographic Provider Types.
[in] dwFlags
Flag values. This parameter is usually set to zero, but some applications set one or more of the following flags.
Return value
If the function succeeds, the function returns nonzero (TRUE).
If the function fails, it returns zero (FALSE). For extended error information, callGetLastError.
The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes defined in Winerror.h follow.
Return code/value | Description |
---|---|
| Some CSPs set this error if the CRYPT_DELETEKEYSET flag value is set and another thread or process is using this key container. |
| The profile of the user is not loaded and cannot be found. This happens when the application impersonates a user, for example, the IUSR_ComputerName account. |
| One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. |
| The operating system ran out of memory during the operation. |
| The dwFlags parameter has a value that is not valid. |
| The user password has changed since the private keys were encrypted. |
| The key container could not be opened. A common cause of this error is that the key container does not exist. To create a key container, call CryptAcquireContext using the CRYPT_NEWKEYSET flag. This error code can also indicate that access to an existing key container is denied. Access rights to the container can be granted by the key set creator by using CryptSetProvParam. |
| The pszContainer or pszProvider parameter is set to a value that is not valid. |
| The value of the dwProvType parameter is out of range. All provider types must be from 1 through 999, inclusive. |
| The provider DLL signature could not be verified. Either the DLL or the digital signature has been tampered with. |
| The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists. |
| The pszContainer key container was found but is corrupt. |
| The requested provider does not exist. |
| The CSP ran out of memory during the operation. |
| The provider DLL file does not exist or is not on the current path. |
| The provider type specified by dwProvType is corrupt. This error can relate to either the user default CSP list or the computer default CSP list. |
| The provider type specified by dwProvType does not match the provider type found. Note that this error can only occur when pszProvider specifies an actual CSP name. |
| No entry exists for the provider type specified by dwProvType. |
| The provider DLL file could not be loaded or failed to initialize. |
| An error occurred while loading the DLL file image, prior to verifying its signature. |
Remarks
The pszContainer parameter specifies the name of the container that is used to hold the key. Each container can contain one key. If you specify the name of an existing container when creating keys, the new key will overwrite a previous one.
The combination of the CSP name and the key container name uniquely identifies a single key on the system. If one application tries to modify a key container while another application is using it, unpredictable behavior may result.
If you set the pszContainer parameter to NULL, the default key container name is used. When the Microsoft software CSPs are called in this manner, a new container is created each time the CryptAcquireContext function is called. However, different CSPs may behave differently in this regard. In particular, a CSP may have a single default container that is shared by all applications accessing the CSP. Therefore, applications must not use the default key container to store private keys. Instead, either prevent key storage by passing the CRYPT_VERIFYCONTEXT flag in the dwFlags parameter, or use an application-specific container that is unlikely to be used by another application.
An application can obtain the name of the key container in use by using theCryptGetProvParam function to read the PP_CONTAINER value.
For performance reasons, we recommend that you set the pszContainer parameter to NULL and the dwFlags parameter to CRYPT_VERIFYCONTEXT in all situations where you do not require a persisted key. In particular, consider setting the pszContainer parameter to NULL and the dwFlags parameter to CRYPT_VERIFYCONTEXT for the following scenarios:
- You are creating a hash.
- You are generating a symmetric key to encrypt or decrypt data.
- You are deriving a symmetric key from a hash to encrypt or decrypt data.
- You are verifying a signature. It is possible to import a public key from a PUBLICKEYBLOB or from a certificate by using CryptImportKey or CryptImportPublicKeyInfo. A context can be acquired by using the CRYPT_VERIFYCONTEXT flag if you only plan to import the public key.
- You plan to export a symmetric key, but not import it within the crypto context's lifetime. A context can be acquired by using the CRYPT_VERIFYCONTEXT flag if you only plan to import the public key for the last two scenarios.
- You are performing private key operations, but you are not using a persisted private key that is stored in a key container.
If you plan to perform private key operations, the best way to acquire a context is to try to open the container. If this attempt fails with NTE_BAD_KEYSET, then create the container by using the CRYPT_NEWKEYSET flag.
Examples
The following example shows acquiring a cryptographic context and access to public/private key pairs in a key container. If the requested key container does not exist, it is created.
For an example that includes the complete context for this example, see Example C Program: Creating a Key Container and Generating Keys. For additional examples, seeExample C Program: Using CryptAcquireContext.
//-------------------------------------------------------------------// Declare and initialize variables.HCRYPTPROV hCryptProv = NULL; // handle for a cryptographic // provider contextLPCSTR UserName = "MyKeyContainer"; // name of the key container // to be used//-------------------------------------------------------------------// Attempt to acquire a context and a key// container. The context will use the default CSP// for the RSA_FULL provider type. DwFlags is set to zero// to attempt to open an existing key container.if(CryptAcquireContext( &hCryptProv, // handle to the CSP UserName, // container name NULL, // use the default provider PROV_RSA_FULL, // provider type 0)) // flag values{ printf("A cryptographic context with the %s key container \n", UserName); printf("has been acquired.\n\n");}else{ //-------------------------------------------------------------------// An error occurred in acquiring the context. This could mean// that the key container requested does not exist. In this case,// the function can be called again to attempt to create a new key // container. Error codes are defined in Winerror.h. if (GetLastError() == NTE_BAD_KEYSET) { if(CryptAcquireContext( &hCryptProv, UserName, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { printf("A new key container has been created.\n"); } else { printf("Could not create a new key container.\n"); exit(1); } } else { printf("A cryptographic service handle could not be " "acquired.\n"); exit(1); } } // End of else.//-------------------------------------------------------------------// A cryptographic context and a key container are available. Perform// any functions that require a cryptographic provider handle.//-------------------------------------------------------------------// When the handle is no longer needed, it must be released.if (CryptReleaseContext(hCryptProv,0)){ printf("The handle has been released.\n");}else{ printf("The handle could not be released.\n");}
Note
The wincrypt.h header defines CryptAcquireContext as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.
Requirements
Requirement | Value |
---|---|
Minimum supported client | WindowsXP [desktop apps only] |
Minimum supported server | Windows Server2003 [desktop apps only] |
Target Platform | Windows |
Header | wincrypt.h |
Library | Advapi32.lib |
DLL | Advapi32.dll |
See also
CryptGenKey
CryptGetProvParam
CryptReleaseContext
Service Provider Functions
Threading Issues with Cryptographic Service Providers