Gebruik en probleemoplossing van CryptAcquireContext()

Dit artikel bevat informatie over het gebruik van specifieke vlaggen wanneer u CryptAcquireContext aanroept en de redenen voor het gebruik van deze vlaggen.

Van toepassing op: Windows Server 2012 R2
Origineel KB-nummer: 238187

Samenvatting

Aanroepen naar de CryptAcquireContext functie kunnen verschillende vlaggen bevatten. Het is belangrijk om te weten wanneer u deze vlaggen moet gebruiken. Dit artikel bevat informatie over wanneer u specifieke vlaggen moet gebruiken wanneer u aanroept CryptAcquireContext en de redenen voor het gebruik van deze vlaggen.

Meer informatie

Privésleutelbewerkingen worden niet uitgevoerd

Als u geen permanente persoonlijke sleutel gebruikt, kan de vlag CRYPT_VERIFYCONTEXT (0xF0000000) worden gebruikt wanneer CryptAcquireContext wordt aangeroepen. Dit vertelt CryptoAPI om een sleutelcontainer in het geheugen te maken die wordt vrijgegeven wanneer CryptReleaseContext wordt aangeroepen. Wanneer deze vlag wordt gebruikt, moet de parameter pszContainer NULL zijn. De vlag CRYPT_VERIFYCONTEXT kan in de volgende scenario's worden gebruikt:

  • U maakt een hash.

  • U genereert een symmetrische sleutel om gegevens te versleutelen of te ontsleutelen.

  • U ontlenen een symmetrische sleutel aan een hash om gegevens te versleutelen of te ontsleutelen.

  • U controleert een handtekening. Het is mogelijk om een openbare sleutel te importeren uit een PUBLICKEYBLOB of uit een certificaat met behulp van CryptImportKey of CryptImportPublicKeyInfo.

  • U bent van plan een symmetrische sleutel te exporteren, maar deze niet te importeren binnen de levensduur van de cryptocontext.

    Opmerking

    Een context kan worden verkregen met behulp van de vlag CRYPT_VERIFYCONTEXT als u alleen van plan bent om de openbare sleutel voor de laatste twee scenario's te importeren.

  • U voert privésleutelbewerkingen uit, maar u gebruikt geen permanente persoonlijke sleutel die is opgeslagen in een sleutelcontainer.

Er worden privésleutelbewerkingen uitgevoerd

Als u van plan bent om bewerkingen met een persoonlijke sleutel uit te voeren, zijn er veel problemen waarmee u rekening moet houden.

De beste manier om een context te verkrijgen, is door te proberen de container te openen. Als deze poging mislukt met 'NTE_BAD_KEYSET', maakt u de container met behulp van de vlag CRYPT_NEWKEYSET.

Opmerking

Toepassingen mogen de standaardsleutelcontainer niet gebruiken door NULL door te geven voor de containernaam om persoonlijke sleutels op te slaan. Wanneer meerdere toepassingen dezelfde container gebruiken, kan één toepassing de sleutels wijzigen of vernietigen die een andere toepassing beschikbaar moet hebben. Als toepassingen gebruikmaken van sleutelcontainers met een unieke naam, wordt het risico verkleind dat andere toepassingen knoeien met sleutels die nodig zijn voor een goede werking.

// Acquire Context of container that is unique to each user.
if (!CryptAcquireContext(&hProv,  
 "Container",  
 NULL,  
 PROV_RSA_FULL,  
 0))
{
 if (GetLastError() == NTE_BAD_KEYSET)
 {
 if (!CryptAcquireContext(&hProv,  
 "Container",  
 NULL,  
 PROV_RSA_FULL,  
 CRYPT_NEWKEYSET))
 {
 // Error ...
 }
 }
}

// Or, acquire Context of container that is shared across the machine.
if (!CryptAcquireContext(&hProv,  
 "Container",  
 NULL,  
 PROV_RSA_FULL,  
 CRYPT_MACHINE_KEYSET))
{
 if (GetLastError() == NTE_BAD_KEYSET)
 {
 if (!CryptAcquireContext(&hProv,  
 "Container",  
 NULL,  
 PROV_RSA_FULL,  
 CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET)
 {
 // Error ...
 }
 }
}

De vlag CRYPT_MACHINE_KEYSET gebruiken

Als u geen privésleutelbewerkingen per gebruiker uitvoert en u globale bewerkingen voor persoonlijke sleutels nodig hebt, moet CRYPT_MACHINE_KEYSET worden gebruikt. Met deze methode wordt het persoonlijke/openbare sleutelpaar per computer gemaakt. Enkele specifieke scenario's waarin CRYPT_MACHINE_KEYSET moeten worden gebruikt, zijn:

  • U schrijft een service.
  • Uw onderdeel wordt uitgevoerd op een ASP-pagina (Active Server Pages).
  • Uw onderdeel is een MTS-onderdeel (Microsoft Transaction Server). Voor deze voorbeelden wordt CRYPT_MACHINE_KEYSET gebruikt omdat de beveiligingscontext waarin de toepassing wordt uitgevoerd geen toegang heeft tot een gebruikersprofiel. Een MTS-client kan bijvoorbeeld een gebruiker imiteren, maar het profiel van de gebruiker is niet beschikbaar omdat de gebruiker niet is aangemeld. Hetzelfde geldt voor een onderdeel dat wordt uitgevoerd op een ASP-pagina.

Toegang verlenen tot uw container

Wanneer een sleutelcontainer wordt gemaakt, zijn het lokale systeem en de maker standaard de enige gebruikers die toegang hebben tot de container. De uitzondering hierop is wanneer een beheerder de sleutelcontainer maakt. Het lokale systeem en alle andere beheerders hebben toegang tot de sleutelcontainer. De container kan niet worden geopend in een andere beveiligingscontext.

Als uw code wordt uitgevoerd onder meer dan één beveiligingscontext, moet u de juiste gebruikers toegang geven tot uw container.

Als u de beveiliging van de container wilt instellen, roept u de functie CryptSetProvParam aan met de vlag PP_KEYSET_SEC_DESCR nadat de container is gemaakt. Met deze methode kunt u de beveiligingsdescriptor voor de container instellen.

De volgende code laat zien hoe u CryptSetProvParam aanroept. Dit gebeurt direct na het maken van de sleutelcontainer.

// Acquire Context  
if (!CryptAcquireContext(&hProv,  
 "Container",  
 NULL,  
 PROV_RSA_FULL,  
 0))
{
 if (GetLastError() == NTE_BAD_KEYSET)
 {
 if (!CryptAcquireContext(&hProv,  
 "Container",  
 NULL,  
 PROV_RSA_FULL,  
 CRYPT_NEWKEYSET))
 {
 // Error ...
 }

// Create Security Descriptor (pSD)...

// Set the Security Descriptor on the container
 if (!CryptSetProvParam(hProv,
 PP_KEYSET_SEC_DESCR,
 pSD,
 DACL_SECURITY_INFORMATION))
 {
 // Error ...
 }
 }
}

CryptAcquireContext-fouten

Hier volgen de meest voorkomende foutcodes en mogelijke redenen voor de fout.

  • NTE_BAD_KEYSET (0x80090016)
    • De sleutelcontainer bestaat niet.
    • U hebt geen toegang tot de sleutelcontainer.
    • De beveiligde opslagservice wordt niet uitgevoerd.
  • NTE_EXISTS (0x8009000F)
    • De sleutelcontainer bestaat al, maar u probeert deze te maken. Als een eerdere poging om de sleutel te openen met NTE_BAD_KEYSET is mislukt, betekent dit dat de toegang tot de sleutelcontainer wordt geweigerd.
  • NTE_KEYSET_NOT_DEF (0x80090019)
    • De Crypto Service Provider (CSP) is mogelijk niet correct ingesteld. Het gebruik van Regsvr32.exe op CSP-DLL's (Rsabase.dll of Rsaenh.dll) kan het probleem oplossen, afhankelijk van de provider die wordt gebruikt.