CryptAcquireContextA-Funktion (wincrypt.h)

Wichtig Diese API ist veraltet. Neue und vorhandene Software sollte mit der Verwendung von Kryptografie-APIs der nächsten Generation beginnen. Microsoft kann diese API in zukünftigen Versionen entfernen.
 
Die CryptAcquireContext-Funktion wird verwendet, um ein Handle für einen bestimmten Schlüsselcontainer innerhalb eines bestimmten Kryptografiedienstanbieters (CSP ) zu erhalten. Dieses zurückgegebene Handle wird in Aufrufen von CryptoAPI-Funktionen verwendet, die den ausgewählten CSP verwenden.

Diese Funktion versucht zunächst, einen CSP mit den in den Parametern dwProvType und szProvider beschriebenen Merkmalen zu finden. Wenn der CSP gefunden wird, versucht die Funktion, einen Schlüsselcontainer innerhalb des CSP zu finden, der mit dem durch den szContainer-Parameter angegebenen Namen übereinstimmt. Verwenden Sie zum Abrufen des Kontexts und des Schlüsselcontainers eines privaten Schlüssels , der dem öffentlichen Schlüssel eines Zertifikats zugeordnet ist, CryptAcquireCertificatePrivateKey.

Mit der entsprechenden Einstellung von dwFlags kann diese Funktion auch Schlüsselcontainer erstellen und zerstören und zugriff auf einen CSP mit einem temporären Schlüsselcontainer gewähren, wenn kein Zugriff auf einen privaten Schlüssel erforderlich ist.

Syntax

BOOL CryptAcquireContextA(
  [out] HCRYPTPROV *phProv,
  [in]  LPCSTR     szContainer,
  [in]  LPCSTR     szProvider,
  [in]  DWORD      dwProvType,
  [in]  DWORD      dwFlags
);

Parameter

[out] phProv

Ein Zeiger auf ein Handle eines CSP. Wenn Sie die Verwendung des CSP abgeschlossen haben, geben Sie das Handle frei, indem Sie die CryptReleaseContext-Funktion aufrufen.

[in] szContainer

Der Schlüsselcontainername. Dies ist eine NULL-Zeichenfolge, die den Schlüsselcontainer für den CSP identifiziert. Dieser Name ist unabhängig von der Methode, die zum Speichern der Schlüssel verwendet wird. Einige CSPs speichern ihre Schlüsselcontainer intern (in Hardware), andere verwenden die Systemregistrierung und andere das Dateisystem. Wenn dwFlags auf CRYPT_VERIFYCONTEXT festgelegt ist, muss szContainer in den meisten Fällen auf NULL festgelegt werden. Für hardwarebasierte CSPs, z. B. einen Smartcard-CSP, kann jedoch auf öffentlich verfügbare Informationen im angegebenen Container zugegriffen werden.

Weitere Informationen zur Verwendung des szContainer-Parameters finden Sie unter Hinweise.

[in] szProvider

Eine NULL-Zeichenfolge, die den Namen des zu verwendenden CSP enthält.

Wenn dieser Parameter NULL ist, wird der Standardanbieter des Benutzers verwendet. Weitere Informationen finden Sie unter Kryptografiedienstanbieterkontexte. Eine Liste der verfügbaren Kryptografieanbieter finden Sie unter Namen von Kryptografieanbietern.

Eine Anwendung kann den Namen des verwendeten CSP abrufen, indem die CryptGetProvParam-Funktion verwendet wird, um den PP_NAME CSP-Wert im dwParam-Parameter zu lesen.

Der Standard-CSP kann zwischen Betriebssystemversionen geändert werden. Um die Interoperabilität auf verschiedenen Betriebssystemplattformen sicherzustellen, sollte der CSP explizit mithilfe dieses Parameters anstelle des Standard-CSP festgelegt werden.

[in] dwProvType

Gibt den Typ des anbieters an, der abgerufen werden soll. Definierte Anbietertypen werden unter Kryptografieanbietertypen erläutert.

[in] dwFlags

Flagwerte. Dieser Parameter wird in der Regel auf 0 (null) festgelegt, aber einige Anwendungen legen mindestens eins der folgenden Flags fest.

Wert Bedeutung
CRYPT_VERIFYCONTEXT
Diese Option ist für Anwendungen vorgesehen, die kurzlebige Schlüssel verwenden, oder Für Anwendungen, die keinen Zugriff auf persistente private Schlüssel benötigen, z. B. Anwendungen, die nur Hashing, Verschlüsselung und Überprüfung digitaler Signaturen ausführen. Nur Anwendungen, die Signaturen erstellen oder Nachrichten entschlüsseln, benötigen Zugriff auf einen privaten Schlüssel. In den meisten Fällen sollte dieses Flag festgelegt werden.

Wenn dieses Flag für dateibasierte CSPs festgelegt ist, muss der parameter szContainer auf NULL festgelegt werden. Die Anwendung hat keinen Zugriff auf die beibehaltenen privaten Schlüssel von Öffentlichen/Privaten Schlüsselpaaren. Wenn dieses Flag festgelegt ist, können temporäre Öffentliche/private Schlüsselpaare erstellt werden, aber sie werden nicht beibehalten.

Wenn der szContainer-Parameter bei hardwarebasierten CSPs, z. B. einem Smartcard-CSP, NULL oder leer ist, bedeutet dieses Flag, dass kein Zugriff auf Schlüssel erforderlich ist und dem Benutzer keine Benutzeroberfläche angezeigt werden sollte. Dieses Formular wird verwendet, um eine Verbindung mit dem CSP herzustellen, um seine Funktionen abzufragen, aber nicht, um seine Schlüssel tatsächlich zu verwenden. Wenn der szContainer-Parameter nicht NULL und nicht leer ist, impliziert dieses Flag, dass nur Zugriff auf die öffentlich verfügbaren Informationen innerhalb des angegebenen Containers erforderlich ist. Der CSP sollte keine PIN anfordern. Versuche, auf private Informationen zuzugreifen (z. B. die CryptSignHash-Funktion ), schlagen fehl.

Wenn CryptAcquireContext aufgerufen wird, benötigen viele CSPs eingaben vom besitzenden Benutzer, bevor sie Zugriff auf die privaten Schlüssel im Schlüsselcontainer gewähren. Beispielsweise können die privaten Schlüssel verschlüsselt werden, sodass ein Kennwort vom Benutzer erforderlich ist, bevor sie verwendet werden können. Wenn jedoch das flag CRYPT_VERIFYCONTEXT angegeben ist, ist kein Zugriff auf die privaten Schlüssel erforderlich, und die Benutzeroberfläche kann umgangen werden.

CRYPT_NEWKEYSET
Erstellt einen neuen Schlüsselcontainer mit dem durch szContainer angegebenen Namen. Wenn szContainerNULL ist, wird ein Schlüsselcontainer mit dem Standardnamen erstellt.
CRYPT_MACHINE_KEYSET
Standardmäßig werden Schlüssel und Schlüsselcontainer als Benutzerschlüssel gespeichert. Für Basisanbieter bedeutet dies, dass Benutzerschlüsselcontainer im Profil des Benutzers gespeichert werden. Auf einen Schlüsselcontainer, der ohne dieses Flag von einem Administrator erstellt wurde, kann nur der Benutzer, der den Schlüsselcontainer erstellt, und ein Benutzer mit Administratorrechten zugreifen.

Windows XP: Auf einen Schlüsselcontainer, der ohne dieses Flag von einem Administrator erstellt wurde, kann nur der Benutzer zugreifen, der den Schlüsselcontainer und das lokale Systemkonto erstellt.

Auf einen Schlüsselcontainer, der ohne dieses Flag von einem Benutzer erstellt wurde, der kein Administrator ist, kann nur der Benutzer zugreifen, der den Schlüsselcontainer und das lokale Systemkonto erstellt.

Das flag CRYPT_MACHINE_KEYSET kann mit allen anderen Flags kombiniert werden, um anzugeben, dass der schlüsselspezifische Container ein Computerschlüsselcontainer ist und der CSP ihn als solchen behandelt. Für Basisanbieter bedeutet dies, dass die Schlüssel lokal auf dem Computer gespeichert werden, der den Schlüsselcontainer erstellt hat. Wenn ein Schlüsselcontainer ein Computercontainer sein soll, muss das flag CRYPT_MACHINE_KEYSET für alle Aufrufe von CryptAcquireContext verwendet werden, die auf den Computercontainer verweisen. Auf den Schlüsselcontainer, der mit CRYPT_MACHINE_KEYSET von einem Administrator erstellt wurde, kann nur der Ersteller und ein Benutzer mit Administratorrechten zugreifen, es sei denn, die Zugriffsrechte für den Container werden mithilfe von CryptSetProvParam erteilt.

Windows XP: Auf den Schlüsselcontainer, der mit CRYPT_MACHINE_KEYSET erstellt wurde, kann nur der Ersteller und das lokale Systemkonto zugreifen, es sei denn, die Zugriffsrechte für den Container werden mithilfe von CryptSetProvParam erteilt.

Auf den Schlüsselcontainer, der mit CRYPT_MACHINE_KEYSET von einem Benutzer erstellt wurde, der kein Administrator ist, kann nur der Ersteller und das lokale Systemkonto zugreifen, es sei denn, die Zugriffsrechte für den Container werden mithilfe von CryptSetProvParam erteilt.

Das CRYPT_MACHINE_KEYSET-Flag ist nützlich, wenn der Benutzer von einem Dienst oder Benutzerkonto aus zugreift, der sich nicht interaktiv angemeldet hat. Wenn Schlüsselcontainer erstellt werden, erstellen die meisten CSPs nicht automatisch öffentliche /private Schlüsselpaare. Diese Schlüssel müssen als separater Schritt mit der CryptGenKey-Funktion erstellt werden.

CRYPT_DELETEKEYSET
Löschen Sie den durch szContainer angegebenen Schlüsselcontainer. Wenn szContainerNULL ist, wird der Schlüsselcontainer mit dem Standardnamen gelöscht. Alle Schlüsselpaare im Schlüsselcontainer werden ebenfalls zerstört.

Wenn dieses Flag festgelegt ist, ist der in phProv zurückgegebene Wert undefiniert, sodass die CryptReleaseContext-Funktion danach nicht aufgerufen werden muss.

CRYPT_SILENT
Die Anwendung fordert an, dass der CSP keine Benutzeroberfläche (UI) für diesen Kontext anzeigt. Wenn der CSP die Benutzeroberfläche für den Betrieb anzeigen muss, schlägt der Aufruf fehl, und der NTE_SILENT_CONTEXT Fehlercode wird als letzter Fehler festgelegt. Wenn Aufrufe von CryptGenKey mit dem flag CRYPT_USER_PROTECTED mit einem Kontext erfolgen, der mit dem flag CRYPT_SILENT abgerufen wurde, schlagen die Aufrufe fehl, und der CSP legt NTE_SILENT_CONTEXT fest.

CRYPT_SILENT ist für die Verwendung mit Anwendungen vorgesehen, für die die Benutzeroberfläche vom CSP nicht angezeigt werden kann.

CRYPT_DEFAULT_CONTAINER_OPTIONAL
Ruft einen Kontext für einen Smartcard-CSP ab, der für Hashing- und Symmetric Key-Vorgänge verwendet werden kann, aber nicht für Vorgänge verwendet werden kann, die eine Authentifizierung bei einer Smartcard mithilfe einer PIN erfordern. Dieser Kontexttyp wird am häufigsten verwendet, um Vorgänge auf einer leeren Smartcard auszuführen, z. B. das Festlegen der PIN mithilfe von CryptSetProvParam. Dieses Flag kann nur mit Smartcard-CSPs verwendet werden.

Windows Server 2003 und Windows XP: Dieses Flag wird nicht unterstützt.

Rückgabewert

Wenn die Funktion erfolgreich ist, gibt die Funktion ungleich null (TRUE) zurück.

Wenn die Funktion fehlschlägt, gibt sie null (FALSE) zurück. Rufen Sie GetLastError auf, um erweiterte Fehlerinformationen zu erhalten.

Die von NTE vorangestellten Fehlercodes werden vom jeweiligen verwendeten CSP generiert. Es folgen einige mögliche Fehlercodes, die in Winerror.h definiert sind.

Rückgabecode/-wert BESCHREIBUNG
ERROR_BUSY
107L
Einige CSPs legen diesen Fehler fest, wenn der CRYPT_DELETEKEYSET-Flagwert festgelegt ist und ein anderer Thread oder Prozess diesen Schlüsselcontainer verwendet.
ERROR_FILE_NOT_FOUND
2L
Das Profil des Benutzers wird nicht geladen und kann nicht gefunden werden. Dies geschieht, wenn die Anwendung die Identität eines Benutzers angibt, z. B. das konto IUSR_ComputerName .
ERROR_INVALID_PARAMETER
87L
Einer der Parameter enthält einen ungültigen Wert. Dies ist in den meisten Fällen ein ungültiger Zeiger.
ERROR_NOT_ENOUGH_MEMORY
8L
Beim Betriebssystem ist während des Vorgangs nicht mehr genügend Arbeitsspeicher vorhanden.
NTE_BAD_FLAGS
0x80090009L
Der dwFlags-Parameter hat einen ungültigen Wert.
NTE_BAD_KEY_STATE
0x8009000BL
Das Benutzerkennwort wurde geändert, seit die privaten Schlüssel verschlüsselt wurden.
NTE_BAD_KEYSET
0x80090016L
Der Schlüsselcontainer konnte nicht geöffnet werden. Eine häufige Ursache für diesen Fehler ist, dass der Schlüsselcontainer nicht vorhanden ist. Um einen Schlüsselcontainer zu erstellen, rufen Sie CryptAcquireContext mit dem flag CRYPT_NEWKEYSET auf. Dieser Fehlercode kann auch angeben, dass der Zugriff auf einen vorhandenen Schlüsselcontainer verweigert wird. Zugriffsrechte für den Container können vom Ersteller des Schlüsselsatzes mithilfe von CryptSetProvParam gewährt werden.
NTE_BAD_KEYSET_PARAM
0x8009001FL
Der szContainer - oder szProvider-Parameter wird auf einen ungültigen Wert festgelegt.
NTE_BAD_PROV_TYPE
0x80090014L
Der Wert des dwProvType-Parameters liegt außerhalb des Bereichs. Alle Anbietertypen müssen zwischen 1 und einschließlich 999 liegen.
NTE_BAD_SIGNATURE
0x80090006L
Die Dll-Signatur des Anbieters konnte nicht überprüft werden. Entweder die DLL oder die digitale Signatur wurde manipuliert.
NTE_EXISTS
0x8009000FL
Der dwFlags-Parameter ist CRYPT_NEWKEYSET, aber der Schlüsselcontainer ist bereits vorhanden.
NTE_KEYSET_ENTRY_BAD
0x8009001AL
Der Schlüsselcontainer szContainer wurde gefunden, ist aber beschädigt.
NTE_KEYSET_NOT_DEF
0x80090019L
Der angeforderte Anbieter ist nicht vorhanden.
NTE_NO_MEMORY
0x8009000EL
Während des Vorgangs war für den CSP der Arbeitsspeicher nicht mehr vorhanden.
NTE_PROV_DLL_NOT_FOUND
0x8009001EL
Die Anbieter-DLL-Datei ist nicht vorhanden oder befindet sich nicht im aktuellen Pfad.
NTE_PROV_TYPE_ENTRY_BAD
0x80090018L
Der von dwProvType angegebene Anbietertyp ist beschädigt. Dieser Fehler kann sich entweder auf die Standard-CSP-Liste des Benutzers oder die Standard-CSP-Liste des Computers beziehen.
NTE_PROV_TYPE_NO_MATCH
0x8009001BL
Der von dwProvType angegebene Anbietertyp stimmt nicht mit dem gefundenen Anbietertyp überein. Beachten Sie, dass dieser Fehler nur auftreten kann, wenn szProvider einen tatsächlichen CSP-Namen angibt.
NTE_PROV_TYPE_NOT_DEF
0x80090017L
Für den von dwProvType angegebenen Anbietertyp ist kein Eintrag vorhanden.
NTE_PROVIDER_DLL_FAIL
0x8009001DL
Die Anbieter-DLL-Datei konnte nicht geladen werden oder konnte nicht initialisiert werden.
NTE_SIGNATURE_FILE_BAD
0x8009001CL
Fehler beim Laden des DLL-Dateiimages vor der Überprüfung der Signatur.

Hinweise

Der szContainer-Parameter gibt den Namen des Containers an, der zum Halten des Schlüssels verwendet wird. Jeder Container kann einen Schlüssel enthalten. Wenn Sie beim Erstellen von Schlüsseln den Namen eines vorhandenen Containers angeben, überschreibt der neue Schlüssel einen vorherigen.

Die Kombination aus dem CSP-Namen und dem Schlüsselcontainernamen identifiziert eindeutig einen einzelnen Schlüssel im System. Wenn eine Anwendung versucht, einen Schlüsselcontainer zu ändern, während eine andere Anwendung ihn verwendet, kann unvorhersehbares Verhalten auftreten.

Wenn Sie den szContainer-Parameter auf NULL festlegen, wird der Standardname des Schlüsselcontainers verwendet. Wenn die Microsoft-Software-CSPs auf diese Weise aufgerufen werden, wird bei jedem Aufruf der CryptAcquireContext-Funktion ein neuer Container erstellt. Verschiedene CSPs können sich in dieser Hinsicht jedoch unterschiedlich verhalten. Insbesondere kann ein CSP über einen einzelnen Standardcontainer verfügen, der von allen Anwendungen gemeinsam genutzt wird, die auf den CSP zugreifen. Daher dürfen Anwendungen den Standardschlüsselcontainer nicht zum Speichern privater Schlüssel verwenden. Verhindern Sie stattdessen die Schlüsselspeicherung, indem Sie das CRYPT_VERIFYCONTEXT-Flag im dwFlags-Parameter übergeben, oder verwenden Sie einen anwendungsspezifischen Container, der wahrscheinlich nicht von einer anderen Anwendung verwendet wird.

Eine Anwendung kann den Namen des verwendeten Schlüsselcontainers abrufen, indem sie die CryptGetProvParam-Funktion zum Lesen des PP_CONTAINER Werts verwendet.

Aus Leistungsgründen empfiehlt es sich, den szContainer-Parameter auf NULL und den dwFlags-Parameter auf CRYPT_VERIFYCONTEXT in allen Situationen festzulegen, in denen Sie keinen dauerhaften Schlüssel benötigen. Erwägen Sie insbesondere das Festlegen des szContainer-Parameters auf NULL und des dwFlags-Parameters auf CRYPT_VERIFYCONTEXT für die folgenden Szenarien:

  • Sie erstellen einen Hash.
  • Sie generieren einen symmetrischen Schlüssel zum Verschlüsseln oder Entschlüsseln von Daten.
  • Sie leiten einen symmetrischen Schlüssel aus einem Hash ab, um Daten zu verschlüsseln oder zu entschlüsseln.
  • Sie überprüfen eine Signatur. Es ist möglich, einen öffentlichen Schlüssel aus einem PUBLICKEYBLOB oder aus einem Zertifikat mithilfe von CryptImportKey oder CryptImportPublicKeyInfo zu importieren. Ein Kontext kann mithilfe des CRYPT_VERIFYCONTEXT-Flags abgerufen werden, wenn Sie nur den öffentlichen Schlüssel importieren möchten.
  • Sie planen, einen symmetrischen Schlüssel zu exportieren, ihn jedoch nicht innerhalb der Lebensdauer des Kryptokontexts zu importieren. Ein Kontext kann mithilfe des CRYPT_VERIFYCONTEXT-Flags abgerufen werden, wenn Sie den öffentlichen Schlüssel nur für die letzten beiden Szenarien importieren möchten.
  • Sie führen Vorgänge mit privaten Schlüsseln aus, verwenden jedoch keinen dauerhaften privaten Schlüssel, der in einem Schlüsselcontainer gespeichert ist.
Wenn Sie Vorgänge mit privaten Schlüsseln durchführen möchten, besteht die beste Möglichkeit zum Abrufen eines Kontexts darin, den Container zu öffnen. Wenn dieser Versuch mit NTE_BAD_KEYSET fehlschlägt, erstellen Sie den Container mithilfe des flags CRYPT_NEWKEYSET .

Beispiele

Das folgende Beispiel zeigt das Abrufen eines kryptografischen Kontexts und des Zugriffs auf öffentliche/private Schlüsselpaare in einem Schlüsselcontainer. Wenn der angeforderte Schlüsselcontainer nicht vorhanden ist, wird er erstellt.

Ein Beispiel, das den vollständigen Kontext für dieses Beispiel enthält, finden Sie unter Beispiel-C-Programm: Erstellen eines Schlüsselcontainers und Generieren von Schlüsseln. Weitere Beispiele finden Sie unter Beispiel-C-Programm: Verwenden von 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");
}

Hinweis

Der wincrypt.h-Header definiert CryptAcquireContext als Alias, der die ANSI- oder Unicode-Version dieser Funktion basierend auf der Definition der UNICODE-Präprozessorkonstante automatisch auswählt. Das Mischen der Verwendung des codierungsneutralen Alias mit Code, der nicht Codierungsneutral ist, kann zu Nichtübereinstimmungen führen, die zu Kompilierungs- oder Laufzeitfehlern führen. Weitere Informationen finden Sie unter Konventionen für Funktionsprototypen.

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows XP [nur Desktop-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [nur Desktop-Apps]
Zielplattform Windows
Kopfzeile wincrypt.h
Bibliothek Advapi32.lib
DLL Advapi32.dll

Weitere Informationen

CryptGenKey

CryptGetProvParam

CryptReleaseContext

Dienstanbieterfunktionen

Threadingprobleme mit Kryptografiedienstanbietern