CryptAcquireContextW function (wincrypt.h)
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, use CryptAcquireCertificatePrivateKey.
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 CryptAcquireContextW(
[out] HCRYPTPROV *phProv,
[in] LPCWSTR szContainer,
[in] LPCWSTR 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, see Cryptographic Service Provider Contexts. For a list of available cryptographic providers, see Cryptographic 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 in Cryptographic Provider Types.
[in] dwFlags
One or more of the following flags. Note, most applications should set the CRYPT_VERIFYCONTEXT flag unless they need to create digital signatures or decrypt messages.
Value | Meaning |
---|---|
|
The caller does not need access to persisted private keys. Apps that use ephemeral keys, or that perform only hashing, encryption, and digital signature verification should set this flag. Only applications that create signatures or decrypt messages need access to a private key (and should not set this flag).
For file-based CSPs, when this flag is set, the pszContainer parameter must be set to NULL. The application has no access to the persisted private keys of public/private key pairs. When this flag is set, temporary public/private key pairs can be created, but they are not persisted. For hardware-based CSPs, such as a smart card CSP, if the pszContainer parameter is NULL or blank, this flag implies that no access to any keys is required, and that no UI should be presented to the user. This form is used to connect to the CSP to query its capabilities but not to actually use its keys. If the pszContainer parameter is not NULL and not blank, then this flag implies that access to only the publicly available information within the specified container is required. The CSP should not ask for a PIN. Attempts to access private information (for example, the CryptSignHash function) will fail. When CryptAcquireContext is called, many CSPs require input from the owning user before granting access to the private keys in the key container. For example, the private keys can be encrypted, requiring a password from the user before they can be used. However, if the CRYPT_VERIFYCONTEXT flag is specified, access to the private keys is not required and the user interface can be bypassed. |
|
Creates a new key container with the name specified by pszContainer. If pszContainer is NULL, a key container with the default name is created. |
|
By default, keys and key containers are stored as user keys. For Base Providers, this means that user key containers are stored in the user's profile. A key container created without this flag by an administrator can be accessed only by the user creating the key container and a user with administration privileges.
Windows XP: A key container created without this flag by an administrator can be accessed only by the user creating the key container and the local system account. A key container created without this flag by a user that is not an administrator can be accessed only by the user creating the key container and the local system account. The CRYPT_MACHINE_KEYSET flag can be combined with all of the other flags to indicate that the key container of interest is a computer key container and the CSP treats it as such. For Base Providers, this means that the keys are stored locally on the computer that created the key container. If a key container is to be a computer container, the CRYPT_MACHINE_KEYSET flag must be used with all calls to CryptAcquireContext that reference the computer container. The key container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only by its creator and by a user with administrator privileges unless access rights to the container are granted using CryptSetProvParam. Windows XP: The key container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only by its creator and by the local system account unless access rights to the container are granted using CryptSetProvParam. The key container created with CRYPT_MACHINE_KEYSET by a user that is not an administrator can be accessed only by its creator and by the local system account unless access rights to the container are granted using CryptSetProvParam. The CRYPT_MACHINE_KEYSET flag is useful when the user is accessing from a service or user account that did not log on interactively. When key containers are created, most CSPs do not automatically create any public/private key pairs. These keys must be created as a separate step with the CryptGenKey function. |
|
Delete the key container specified by pszContainer. If pszContainer is NULL, the key container with the default name is deleted. All key pairs in the key container are also destroyed.
When this flag is set, the value returned in phProv is undefined, and thus, the CryptReleaseContext function need not be called afterward. |
|
The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI to operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error. In addition, if calls are made to CryptGenKey with the CRYPT_USER_PROTECTED flag with a context that has been acquired with the CRYPT_SILENT flag, the calls fail and the CSP sets NTE_SILENT_CONTEXT.
CRYPT_SILENT is intended for use with applications for which the UI cannot be displayed by the CSP. |
|
Obtains a context for a smart card CSP that can be used for hashing and symmetric key operations but cannot be used for any operation that requires authentication to a smart card using a PIN. This type of context is most often used to perform operations on an empty smart card, such as setting the PIN by using CryptSetProvParam. This flag can only be used with smart card CSPs.
Windows Server 2003 and Windows XP: This flag is not supported. |
Return value
If the function succeeds, the function returns nonzero (TRUE).
If the function fails, it returns zero (FALSE). For extended error information, call GetLastError.
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 the CryptGetProvParam 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.
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, see Example C Program: Using CryptAcquireContext.
//-------------------------------------------------------------------
// Declare and initialize variables.
HCRYPTPROV hCryptProv = NULL; // handle for a cryptographic
// provider context
LPCSTR 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 that 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 is 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 | Windows XP [desktop apps only] |
Minimum supported server | Windows Server 2003 [desktop apps only] |
Target Platform | Windows |
Header | wincrypt.h |
Library | Advapi32.lib |
DLL | Advapi32.dll |