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, 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 WINAPI CryptAcquireContext(
__out HCRYPTPROV* phProv,
__in LPCTSTR pszContainer,
__in LPCTSTR pszProvider,
__in DWORD dwProvType,
__in DWORD dwFlags
);
Parameters
- phProv
-
A pointer to a handle of a CSP. When you have finished using the CSP, release the handle by calling the CryptReleaseContext function.
- pszContainer
-
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. When dwFlags is set to CRYPT_VERIFYCONTEXT, pszContainer must be set to NULL.
When pszContainer is NULL, a default key container name is used. For example, the Microsoft Base Cryptographic Provider uses the logon name of the currently logged on user as the key container name. Other CSPs can also have default key containers that can be acquired in this way.
Applications must not use the default key container to store private keys. When multiple applications use the same container, one application can change or destroy the keys that another application needs to have available. If applications use key containers linked to the application, the risk is reduced of other applications tampering with keys necessary for proper function.
An application can obtain the name of the key container in use by reading the PP_CONTAINER value with the
CryptGetProvParam function.
- pszProvider
-
A null-terminated string that specifies 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.
Due to changing export control restrictions, 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.
- dwProvType
-
Specifies the type of provider to acquire. Defined provider types are discussed in
Cryptographic Provider Types.
- dwFlags
-
Flag values. This parameter is usually set to zero, but some applications set one or more of the following flags.
| Value | Meaning |
| CRYPT_VERIFYCONTEXT | This option is intended for applications that are using ephemeral keys, or applications that do not require access to persisted private keys, such as applications that perform only hashing, encryption, and digital signature verification. Only applications that create signatures or decrypt messages need access to a private key. In most cases, this flag should be set. 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. |
| CRYPT_NEWKEYSET | Creates a new key container with the name specified by pszContainer. If pszContainer is NULL, a key container with the default name is created. |
| CRYPT_MACHINE_KEYSET | 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. |
| CRYPT_DELETEKEYSET | 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. |
| CRYPT_SILENT | 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. |
| CRYPT_DEFAULT_CONTAINER_OPTIONAL | 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, Windows XP, and Windows 2000: 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 | Description |
| ERROR_BUSY ( 107L ) | Some CSPs set this error if the CRYPT_DELETEKEYSET flag value is set and another thread or process is using this key container. |
| ERROR_FILE_NOT_FOUND ( 2L ) | 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. |
| ERROR_INVALID_PARAMETER ( 87L ) | One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. |
| ERROR_NOT_ENOUGH_MEMORY ( 8L ) | The operating system ran out of memory during the operation. |
| NTE_BAD_FLAGS ( 0x80090009L ) | The dwFlags parameter has a value that is not valid. |
| NTE_BAD_KEY_STATE ( 0x8009000BL ) | The user password has changed since the private keys were encrypted. |
| NTE_BAD_KEYSET( 0x80090016L ) | 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. |
| NTE_BAD_KEYSET_PARAM( 0x8009001FL ) | The pszContainer or pszProvider parameter is set to a value that is not valid. |
| NTE_BAD_PROV_TYPE( 0x80090014L ) | The value of the dwProvType parameter is out of range. All provider types must be from 1 through 999, inclusive. |
| NTE_BAD_SIGNATURE( 0x80090006L ) | The provider DLL signature could not be verified. Either the DLL or the digital signature has been tampered with. |
| NTE_EXISTS( 0x8009000FL ) | The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists. |
| NTE_KEYSET_ENTRY_BAD( 0x8009001AL ) | The pszContainer key container was found but is corrupt. |
| NTE_KEYSET_NOT_DEF( 0x80090019L ) | The key container specified by pszContainer does not exist, or the requested provider does not exist. |
| NTE_NO_MEMORY( 0x8009000EL ) | The CSP ran out of memory during the operation. |
| NTE_PROV_DLL_NOT_FOUND( 0x8009001EL ) | The provider DLL file does not exist or is not on the current path. |
| NTE_PROV_TYPE_ENTRY_BAD( 0x80090018L ) | 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. |
| NTE_PROV_TYPE_NO_MATCH( 0x8009001BL ) | 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. |
| NTE_PROV_TYPE_NOT_DEF( 0x80090017L ) | No entry exists for the provider type specified by dwProvType. |
| NTE_PROVIDER_DLL_FAIL( 0x8009001DL ) | The provider DLL file could not be loaded or failed to initialize. |
| NTE_SIGNATURE_FILE_BAD( 0x8009001CL ) | An error occurred while loading the DLL file image, prior to verifying its signature. |
Example Code
[C++]
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");
}
Requirements
| Client | Requires Windows Vista, Windows XP, or Windows 2000 Professional. |
| Server | Requires Windows Server 2008, Windows Server 2003, or Windows 2000 Server. |
| Header | Declared in Wincrypt.h. |
| Library | Use Advapi32.lib. |
| DLL | Requires Advapi32.dll. |
| Unicode | Implemented as CryptAcquireContextW (Unicode) and CryptAcquireContextA (ANSI). |
See Also
Service Provider Functions
Threading Issues with Cryptographic Service Providers
CryptGenKey
CryptGetProvParam
CryptReleaseContext
Send comments about this topic to Microsoft
Build date: 4/24/2008