Freigeben über


CryptAcquireContextW-Funktion (wincrypt.h)

Wichtig Diese API ist veraltet. Neue und vorhandene Software sollten mit der Verwendung von Kryptografie-APIs der nächsten Generation beginnen. Microsoft kann diese API in zukünftigen Releases 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 pszProvider beschriebenen Merkmalen zu finden. Wenn der CSP gefunden wird, versucht die Funktion, einen Schlüsselcontainer innerhalb des CSP zu finden, der dem durch den pszContainer-Parameter angegebenen Namen entspricht. 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 den Zugriff auf einen CSP mit einem temporären Schlüsselcontainer ermöglichen, wenn kein Zugriff auf einen privaten Schlüssel erforderlich ist.

Syntax

BOOL CryptAcquireContextW(
  [out] HCRYPTPROV *phProv,
  [in]  LPCWSTR    szContainer,
  [in]  LPCWSTR    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, lassen Sie das Handle los, 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 der Hardware), andere verwenden die Systemregistrierung und andere das Dateisystem. Wenn dwFlags auf CRYPT_VERIFYCONTEXT festgelegt ist, muss pszContainer in den meisten Fällen auf NULL festgelegt werden. Für hardwarebasierte CSPs, z. B. eine intelligente Karte CSP, kann jedoch auf öffentlich verfügbare Informationen im angegebenen Container zugegriffen werden.

Weitere Informationen zur Verwendung des pszContainer-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 Benutzerstandardanbieter verwendet. Weitere Informationen finden Sie unter Kontexte von Kryptografiedienstanbietern. Eine Liste der verfügbaren Kryptografieanbieter finden Sie unter Namen von Kryptografieanbietern.

Eine Anwendung kann den Namen des verwendeten CSP abrufen, indem sie die CryptGetProvParam-Funktion verwendet, 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 festgelegt werden, anstatt den Standard-CSP zu verwenden.

[in] dwProvType

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

[in] dwFlags

Mindestens eines der folgenden Flags: Beachten Sie, dass die meisten Anwendungen das CRYPT_VERIFYCONTEXT-Flag festlegen sollten, es sei denn, sie müssen digitale Signaturen erstellen oder Nachrichten entschlüsseln.

Wert Bedeutung
CRYPT_VERIFYCONTEXT
Der Aufrufer benötigt keinen Zugriff auf persistente private Schlüssel. Apps, die kurzlebige Schlüssel verwenden oder nur Hashing, Verschlüsselung und überprüfung der digitalen Signatur ausführen, sollten dieses Flag festlegen. Nur Anwendungen, die Signaturen erstellen oder Nachrichten entschlüsseln, benötigen Zugriff auf einen privaten Schlüssel (und sollte dieses Flag nicht festlegen).

Wenn dieses Flag für dateibasierte CSPs festgelegt ist, muss der pszContainer-Parameter 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.

Bei hardwarebasierten CSPs, z. B. einem smarten Karte CSP, bedeutet dieses Flag, dass kein Zugriff auf Schlüssel erforderlich ist und dem Benutzer keine Benutzeroberfläche angezeigt werden soll, wenn der pszContainer-ParameterNULL oder leer ist. 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 pszContainer-Parameter nicht NULL und nicht leer ist, bedeutet 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 besitzereigenen Benutzer, bevor sie zugriff auf die privaten Schlüssel im Schlüsselcontainer gewähren. Beispielsweise können die privaten Schlüssel verschlüsselt werden, wobei ein Kennwort vom Benutzer erforderlich ist, bevor sie verwendet werden können. Wenn jedoch das Flag CRYPT_VERIFYCONTEXT angegeben ist, ist der Zugriff auf die privaten Schlüssel nicht erforderlich, und die Benutzeroberfläche kann umgangen werden.

CRYPT_NEWKEYSET
Erstellt einen neuen Schlüsselcontainer mit dem von pszContainer angegebenen Namen. Wenn pszContainerNULL 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 es sich bei dem relevanten Schlüsselcontainer um einen Computerschlüsselcontainer handelt und der CSP ihn als solche 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 CRYPT_MACHINE_KEYSET-Flag 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 gewährt.

Windows XP: Auf den Schlüsselcontainer, der mit CRYPT_MACHINE_KEYSET von einem Administrator 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 gewährt.

Das CRYPT_MACHINE_KEYSET-Flag ist nützlich, wenn der Benutzer von einem Dienst oder Benutzerkonto aus zugreift, das 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 Funktion CryptGenKey erstellt werden.

CRYPT_DELETEKEYSET
Löschen Sie den von pszContainer angegebenen Schlüsselcontainer. Wenn pszContainerNULL 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 undefined, sodass die CryptReleaseContext-Funktion nachher 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 anzeigen muss, um zu funktionieren, schlägt der Aufruf fehl, und der NTE_SILENT_CONTEXT Fehlercode wird als letzter Fehler festgelegt. Wenn außerdem Aufrufe an CryptGenKey mit dem CRYPT_USER_PROTECTED-Flag mit einem Kontext ausgeführt werden, der mit dem CRYPT_SILENT-Flag 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 intelligenten Karte-CSP ab, der für Hashing- und symmetrische Schlüsselvorgänge verwendet werden kann, aber nicht für vorgänge verwendet werden kann, die eine Authentifizierung bei einem intelligenten Karte mithilfe einer PIN erfordern. Diese Art von Kontext wird am häufigsten verwendet, um Vorgänge für eine leere intelligente Karte auszuführen, z. B. das Festlegen der PIN mithilfe von CryptSetProvParam. Dieses Flag kann nur mit smarten Karte-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 nonzero (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 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 nicht gültiger Zeiger.
ERROR_NOT_ENOUGH_MEMORY
8L
Während des Vorgangs ging dem Betriebssystem der Arbeitsspeicher aus.
NTE_BAD_FLAGS
0x80090009L
Der dwFlags-Parameter verfügt über 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 parameter pszContainer oder pszProvider ist 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 von 1 bis einschließlich 999 liegen.
NTE_BAD_SIGNATURE
0x80090006L
Die Anbieter-DLL-Signatur 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 pszContainer 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 ging dem CSP der Arbeitsspeicher aus.
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 CSP-Standardliste des Benutzers oder auf 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 pszProvider 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 parameter pszContainer 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 Container.

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 er von einer anderen Anwendung verwendet wird, kann unvorhersehbares Verhalten auftreten.

Wenn Sie den pszContainer-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 freigegeben wird, die auf den CSP zugreifen. Daher dürfen Anwendungen nicht den Standardschlüsselcontainer verwenden, um private Schlüssel zu speichern. 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 pszContainer-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, den pszContainer-Parameter auf NULL und den dwFlags-Parameter auf CRYPT_VERIFYCONTEXT für die folgenden Szenarien festzulegen:

  • 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 zu importieren, indem Sie CryptImportKey oder CryptImportPublicKeyInfo verwenden. Ein Kontext kann mithilfe des CRYPT_VERIFYCONTEXT-Flags abgerufen werden, wenn Sie nur planen, den öffentlichen Schlüssel zu importieren.
  • Sie planen, einen symmetrischen Schlüssel zu exportieren, aber nicht innerhalb der Lebensdauer des Kryptokontexts zu importieren. Ein Kontext kann mithilfe des CRYPT_VERIFYCONTEXT-Flags abgerufen werden, wenn Sie nur planen, den öffentlichen Schlüssel für die letzten beiden Szenarien zu importieren.
  • Sie führen Vorgänge mit privatem Schlüssel aus, verwenden jedoch keinen dauerhaften privaten Schlüssel, der in einem Schlüsselcontainer gespeichert ist.
Wenn Sie Vorgänge mit privatem Schlüssel ausführen möchten, besteht die beste Möglichkeit zum Abrufen eines Kontexts darin, zu versuchen, 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 automatisch die ANSI- oder Unicode-Version dieser Funktion basierend auf der Definition der UNICODE-Präprozessorkonstante auswählt. Das Mischen der Verwendung des codierungsneutralen Alias mit nicht codierungsneutralem Code 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