Over the past few days, some readers have come across the well-known error message Error 0 during the crypto get context. This problem can occur for several reasons. Let’s discuss this below.
This article provides detailed information on when to use certain red flags when calling CryptAcquireContext, as well as the reasons for using these flags.
Applies to: Windows Server 2012 R2
Original KB number: 238187
Calls to any
CryptAcquireContext function can contain various flags. Is it important to know when to use these flags? This article provides information about when certain flags are used when calling
CryptAcquireContext and why these types of flags are used.
Private Key Operations Cannot Be Performed
If you are not using a persistent private key, you can use the CRYPT_VERIFYCONTEXT PIN (0xF0000000) if you can call CryptAcquireContext. This tells the CryptoAPI to create an in-memory key container, which is likely to be released on a normal call to CryptReleaseContext. If this flag is used, the pszContainer parameter must be NULL. The CRYPT_VERIFYCONTEXT flag can be used in the following cases:
The result is a hash.
You generate a symmetric key to encrypt or decrypt knowledge.
Each of them receives a symmetric key from a hash to encrypt and decrypt data.
You are checking the signature. It is possible to import a blocking public key from a PUBLICKEYBLOB or entirely from a certificate using CryptImportKey or possibly CryptImportPublicKeyInfo.
You plan to export the symmetric key, but import it when the encryption context expires.
It’s perfectly possible to get the context using the CRYPT_VERIFYCONTEXT flag if you currently only plan to import the public key for the last two scenarios.
You are performing operations on a single key, but you are not using a persistent private key, which is mostly stored in the engineering container.
Private Key Operations Being Performed
In general, when you want to perform operations on a private key, you really need to consider a lot of things.
The best way to get information by context is to try to make the container available. If this attempt isFailed with “NTE_BAD_KEYSET”, create a cylinder with the CRYPT_NEWKEYSET flag.
// Obtaining a container context is unique for each user.if (!CryptAcquireContext(&hProv, "Container", ZERO, PROV_RSA_FULL, 0)) in case (GetLastError() == NTE_BAD_KEYSET) if (!CryptAcquireContext(&hProv, "Container", ZERO, PROV_RSA_FULL, CRYPT_NEWKEYSET)) Mistake // ... // Or get the container context that contains the entire computer.if (!cryptacquirecontext(&hprov, "Container", ZERO, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) provided (GetLastError() == NTE_BAD_KEYSET) if (!cryptacquirecontext(&hprov, "Container", ZERO, PROV_RSA_FULL, CRYPT_NEWKEYSET
Use The CRYPT_MACHINE_KEYSET Flag
If you’re specifically doing per-user private key operations and need custom global key operations, you should definitely use CRYPT_MACHINE_KEYSET. This method generates a private/public key pair for a specific computer. Some specific scenarios where CRYPT_MACHINE_KEYSET is known to be used:
Give Access To The Main Container
By default, when the main container is created, the local console and the creator are separate users with access to the container type. The exception is, of course, when an administrator creates an important container. Local and system administrators from all other administrators have access to the key container. Any protection and any context cannot open the container.
If your useful code runs in multiple security contexts, you need to give the appropriate users access to your JAR file.
To set security for all containers, call the CryptSetProvParam function with the PP_KEYSET_SEC_DESCR flag after creating the conditional box. This methThe code allows someone to set a security descriptor on a container.
The following code shows which method to call CryptSetProvParam. This is done right after the startup key is created.
// Get the contextif (!CryptAcquireContext(&hProv, "Container", ZERO, PROV_RSA_FULL, 0)) if (GetLastError() == NTE_BAD_KEYSET) if it turns out (!CryptAcquireContext(&hProv, "Container", ZERO, PROV_RSA_FULL, CRYPT_NEWKEYSET)) Mistake // ... // create a security descriptor (PSD)...// Set a specific security descriptor for the container just in case (!CryptSetProvParam(hProv, PP_KEYSET_SEC_DESCR, PSD, DACL_SECURITY_INFORMATION)) // Mistake ...
Here are the most common coupon errors and possible reasons why someone made the mistake.