Partager via


Fonction CryptAcquireContextW (wincrypt.h)

Important Cette API est déconseillée. Les logiciels nouveaux et existants doivent commencer à utiliser les API de nouvelle génération de chiffrement. Microsoft peut supprimer cette API dans les versions ultérieures.
 
La fonction CryptAcquireContext est utilisée pour acquérir un handle pour un conteneur de clés particulier au sein d’un fournisseur de services de chiffrement (CSP) particulier. Ce handle retourné est utilisé dans les appels aux fonctions CryptoAPI qui utilisent le fournisseur csp sélectionné.

Cette fonction tente d’abord de trouver un fournisseur de solutions Cloud avec les caractéristiques décrites dans les paramètres dwProvType et pszProvider . Si le fournisseur de solutions Cloud est trouvé, la fonction tente de trouver un conteneur de clé dans le csp qui correspond au nom spécifié par le paramètre pszContainer . Pour acquérir le contexte et le conteneur de clé d’une clé privée associée à la clé publique d’un certificat, utilisez CryptAcquireCertificatePrivateKey.

Avec le paramètre approprié de dwFlags, cette fonction peut également créer et détruire des conteneurs de clés et peut fournir l’accès à un fournisseur de solutions Cloud avec un conteneur de clés temporaire si l’accès à une clé privée n’est pas nécessaire.

Syntaxe

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

Paramètres

[out] phProv

Pointeur vers un handle d’un fournisseur de solutions Cloud. Une fois que vous avez terminé d’utiliser le fournisseur de solutions Cloud, relâchez le handle en appelant la fonction CryptReleaseContext .

[in] szContainer

Nom du conteneur de clé. Il s’agit d’une chaîne terminée par un caractère Null qui identifie le conteneur de clé pour le fournisseur de solutions Cloud. Ce nom est indépendant de la méthode utilisée pour stocker les clés. Certains fournisseurs de services cloud stockent leurs conteneurs de clés en interne (dans du matériel), d’autres utilisent le registre système et d’autres le système de fichiers. Dans la plupart des cas, lorsque dwFlags est défini sur CRYPT_VERIFYCONTEXT, pszContainer doit avoir la valeur NULL. Toutefois, pour les fournisseurs de services cloud basés sur le matériel, tels qu’un fournisseur de solutions Cloud carte intelligente, peuvent accéder aux informations disponibles publiquement dans le conteneur spécifié.

Pour plus d’informations sur l’utilisation du paramètre pszContainer , consultez Remarques.

[in] szProvider

Chaîne terminée par null qui contient le nom du fournisseur csp à utiliser.

Si ce paramètre a la valeur NULL, le fournisseur par défaut de l’utilisateur est utilisé. Pour plus d’informations, consultez Contextes du fournisseur de services de chiffrement. Pour obtenir la liste des fournisseurs de chiffrement disponibles, consultez Noms des fournisseurs de chiffrement.

Une application peut obtenir le nom du fournisseur de solutions cloud en cours d’utilisation à l’aide de la fonction CryptGetProvParam pour lire la valeur csp PP_NAME dans le paramètre dwParam .

Le fournisseur de solutions Cloud par défaut peut changer d’une version de système d’exploitation à l’autre. Pour garantir l’interopérabilité sur différentes plateformes de système d’exploitation, le csp doit être défini explicitement à l’aide de ce paramètre au lieu d’utiliser le fournisseur de solutions Cloud par défaut.

[in] dwProvType

Spécifie le type de fournisseur à acquérir. Les types de fournisseurs définis sont décrits dans Types de fournisseurs de chiffrement.

[in] dwFlags

Un ou plusieurs des indicateurs suivants. Notez que la plupart des applications doivent définir l’indicateur CRYPT_VERIFYCONTEXT , sauf si elles doivent créer des signatures numériques ou déchiffrer des messages.

Valeur Signification
CRYPT_VERIFYCONTEXT
L’appelant n’a pas besoin d’accéder aux clés privées persistantes. Les applications qui utilisent des clés éphémères ou qui effectuent uniquement le hachage, le chiffrement et la vérification de la signature numérique doivent définir cet indicateur. Seules les applications qui créent des signatures ou déchiffrent des messages ont besoin d’accéder à une clé privée (et ne doivent pas définir cet indicateur).

Pour les fournisseurs de services cloud basés sur des fichiers, lorsque cet indicateur est défini, le paramètre pszContainer doit avoir la valeur NULL. L’application n’a pas accès aux clés privées persistantes des paires de clés publiques/privées. Lorsque cet indicateur est défini, des paires de clés publiques/privées temporaires peuvent être créées , mais elles ne sont pas conservées.

Pour les fournisseurs de services cloud matériels, tels qu’un fournisseur de solutions cloud carte intelligente, si le paramètre pszContainer est NULL ou vide, cet indicateur implique qu’aucun accès à des clés n’est requis et qu’aucune interface utilisateur ne doit être présentée à l’utilisateur. Ce formulaire est utilisé pour se connecter au fournisseur de solutions Cloud afin d’interroger ses fonctionnalités, mais pas pour utiliser réellement ses clés. Si le paramètre pszContainer n’est pas NULL et n’est pas vide, cet indicateur implique que l’accès aux seules informations disponibles publiquement dans le conteneur spécifié est requis. Le fournisseur de solutions Cloud ne doit pas demander de code confidentiel. Les tentatives d’accès aux informations privées (par exemple, la fonction CryptSignHash ) échouent.

Lorsque CryptAcquireContext est appelé, de nombreux fournisseurs de services cloud nécessitent une entrée de l’utilisateur propriétaire avant d’accorder l’accès aux clés privées dans le conteneur de clés. Par exemple, les clés privées peuvent être chiffrées, nécessitant un mot de passe de l’utilisateur avant de pouvoir être utilisées. Toutefois, si l’indicateur CRYPT_VERIFYCONTEXT est spécifié, l’accès aux clés privées n’est pas nécessaire et l’interface utilisateur peut être contournée.

CRYPT_NEWKEYSET
Crée un conteneur de clés avec le nom spécifié par pszContainer. Si pszContainer a la valeur NULL, un conteneur de clés avec le nom par défaut est créé.
CRYPT_MACHINE_KEYSET
Par défaut, les clés et les conteneurs de clés sont stockés en tant que clés utilisateur. Pour les fournisseurs de base, cela signifie que les conteneurs de clés utilisateur sont stockés dans le profil de l’utilisateur. Un conteneur de clés créé sans cet indicateur par un administrateur est accessible uniquement par l’utilisateur qui crée le conteneur de clés et un utilisateur disposant de privilèges d’administration.

Windows XP : Un conteneur de clés créé sans cet indicateur par un administrateur est accessible uniquement par l’utilisateur qui crée le conteneur de clés et le compte système local.

Un conteneur de clés créé sans cet indicateur par un utilisateur qui n’est pas administrateur est accessible uniquement par l’utilisateur qui crée le conteneur de clés et le compte système local.

L’indicateur CRYPT_MACHINE_KEYSET peut être combiné avec tous les autres indicateurs pour indiquer que le conteneur de clé qui vous intéresse est un conteneur de clés d’ordinateur et que le fournisseur de solutions Cloud le traite comme tel. Pour les fournisseurs de base, cela signifie que les clés sont stockées localement sur l’ordinateur qui a créé le conteneur de clés. Si un conteneur de clés doit être un conteneur d’ordinateur, l’indicateur CRYPT_MACHINE_KEYSET doit être utilisé avec tous les appels à CryptAcquireContext qui référencent le conteneur d’ordinateur. Le conteneur de clés créé avec CRYPT_MACHINE_KEYSET par un administrateur est accessible uniquement par son créateur et par un utilisateur disposant de privilèges d’administrateur, sauf si des droits d’accès au conteneur sont accordés à l’aide de CryptSetProvParam.

Windows XP : Le conteneur de clés créé avec CRYPT_MACHINE_KEYSET par un administrateur est accessible uniquement par son créateur et par le compte système local, sauf si des droits d’accès au conteneur sont accordés à l’aide de CryptSetProvParam.

Le conteneur de clés créé avec CRYPT_MACHINE_KEYSET par un utilisateur qui n’est pas administrateur est accessible uniquement par son créateur et par le compte système local, sauf si des droits d’accès au conteneur sont accordés à l’aide de CryptSetProvParam.

L’indicateur CRYPT_MACHINE_KEYSET est utile lorsque l’utilisateur accède à partir d’un service ou d’un compte d’utilisateur qui ne s’est pas connecté de manière interactive. Lorsque des conteneurs de clés sont créés, la plupart des fournisseurs de solutions cloud ne créent pas automatiquement de paires de clés publiques/privées. Ces clés doivent être créées en tant qu’étape distincte avec la fonction CryptGenKey .

CRYPT_DELETEKEYSET
Supprimez le conteneur de clés spécifié par pszContainer. Si pszContainer a la valeur NULL, le conteneur de clés portant le nom par défaut est supprimé. Toutes les paires de clés dans le conteneur de clés sont également détruites.

Lorsque cet indicateur est défini, la valeur retournée dans phProv n’est pas définie et, par conséquent, la fonction CryptReleaseContext n’a pas besoin d’être appelée par la suite.

CRYPT_SILENT
L’application demande que le fournisseur de solutions Cloud n’affiche aucune interface utilisateur (IU) pour ce contexte. Si le fournisseur de solutions Cloud doit afficher l’interface utilisateur pour fonctionner, l’appel échoue et le code d’erreur NTE_SILENT_CONTEXT est défini comme dernière erreur. En outre, si des appels sont effectués à CryptGenKey avec l’indicateur CRYPT_USER_PROTECTED avec un contexte qui a été acquis avec l’indicateur CRYPT_SILENT, les appels échouent et les jeux csp NTE_SILENT_CONTEXT.

CRYPT_SILENT est destiné à être utilisé avec des applications pour lesquelles l’interface utilisateur ne peut pas être affichée par le fournisseur de solutions Cloud.

CRYPT_DEFAULT_CONTAINER_OPTIONAL
Obtient un contexte pour un fournisseur de services de carte intelligent qui peut être utilisé pour les opérations de hachage et de clé symétrique, mais ne peut pas être utilisé pour toute opération nécessitant l’authentification auprès d’un carte intelligent à l’aide d’un code confidentiel. Ce type de contexte est le plus souvent utilisé pour effectuer des opérations sur un carte intelligent vide, comme la définition du code confidentiel à l’aide de CryptSetProvParam. Cet indicateur ne peut être utilisé qu’avec les fournisseurs de services cloud carte intelligents.

Windows Server 2003 et Windows XP : Cet indicateur n’est pas pris en charge.

Valeur retournée

Si la fonction réussit, la fonction retourne une valeur différente de zéro (TRUE).

Si la fonction échoue, elle retourne zéro (FALSE). Pour obtenir des informations d’erreur étendues, appelez GetLastError.

Les codes d’erreur préfacés par NTE sont générés par le fournisseur de solutions Cloud particulier utilisé. Voici quelques codes d’erreur possibles définis dans Winerror.h.

Code/valeur de retour Description
ERROR_BUSY
107L
Certains fournisseurs de services cloud définissent cette erreur si la valeur de l’indicateur CRYPT_DELETEKEYSET est définie et qu’un autre thread ou processus utilise ce conteneur de clés.
ERROR_FILE_NOT_FOUND
2L
Le profil de l’utilisateur n’est pas chargé et est introuvable. Cela se produit lorsque l’application emprunte l’identité d’un utilisateur, par exemple, le compte IUSR_ComputerName .
ERROR_INVALID_PARAMETER
87L
L’un des paramètres contient une valeur qui n’est pas valide. Il s’agit le plus souvent d’un pointeur qui n’est pas valide.
ERROR_NOT_ENOUGH_MEMORY
8L
Le système d’exploitation a manqué de mémoire pendant l’opération.
NTE_BAD_FLAGS
0x80090009L
Le paramètre dwFlags a une valeur qui n’est pas valide.
NTE_BAD_KEY_STATE
0x8009000BL
Le mot de passe utilisateur a changé depuis que les clés privées ont été chiffrées.
NTE_BAD_KEYSET
0x80090016L
Impossible d’ouvrir le conteneur de clés. Une cause courante de cette erreur est que le conteneur de clé n’existe pas. Pour créer un conteneur de clés, appelez CryptAcquireContext à l’aide de l’indicateur CRYPT_NEWKEYSET. Ce code d’erreur peut également indiquer que l’accès à un conteneur de clé existant est refusé. Les droits d’accès au conteneur peuvent être accordés par le créateur du jeu de clés à l’aide de CryptSetProvParam.
NTE_BAD_KEYSET_PARAM
0x8009001FL
Le paramètre pszContainer ou pszProvider est défini sur une valeur non valide.
NTE_BAD_PROV_TYPE
0x80090014L
La valeur du paramètre dwProvType est hors de portée. Tous les types de fournisseurs doivent être compris entre 1 et 999, inclus.
NTE_BAD_SIGNATURE
0x80090006L
La signature DLL du fournisseur n’a pas pu être vérifiée. La DLL ou la signature numérique a été falsifiée.
NTE_EXISTS
0x8009000FL
Le paramètre dwFlags est CRYPT_NEWKEYSET, mais le conteneur de clé existe déjà.
NTE_KEYSET_ENTRY_BAD
0x8009001AL
Le conteneur de clé pszContainer a été trouvé, mais est endommagé.
NTE_KEYSET_NOT_DEF
0x80090019L
Le fournisseur demandé n’existe pas.
NTE_NO_MEMORY
0x8009000EL
Le fournisseur de solutions cloud a manqué de mémoire pendant l’opération.
NTE_PROV_DLL_NOT_FOUND
0x8009001EL
Le fichier DLL du fournisseur n’existe pas ou ne figure pas sur le chemin d’accès actuel.
NTE_PROV_TYPE_ENTRY_BAD
0x80090018L
Le type de fournisseur spécifié par dwProvType est endommagé. Cette erreur peut concerner la liste csp par défaut de l’utilisateur ou la liste CSP par défaut de l’ordinateur.
NTE_PROV_TYPE_NO_MATCH
0x8009001BL
Le type de fournisseur spécifié par dwProvType ne correspond pas au type de fournisseur trouvé. Notez que cette erreur ne peut se produire que lorsque pszProvider spécifie un nom CSP réel.
NTE_PROV_TYPE_NOT_DEF
0x80090017L
Il n’existe aucune entrée pour le type de fournisseur spécifié par dwProvType.
NTE_PROVIDER_DLL_FAIL
0x8009001DL
Le fichier DLL du fournisseur n’a pas pu être chargé ou n’a pas pu être initialisé.
NTE_SIGNATURE_FILE_BAD
0x8009001CL
Une erreur s’est produite lors du chargement de l’image de fichier DLL, avant de vérifier sa signature.

Remarques

Le paramètre pszContainer spécifie le nom du conteneur utilisé pour contenir la clé. Chaque conteneur peut contenir une clé. Si vous spécifiez le nom d’un conteneur existant lors de la création de clés, la nouvelle clé remplace une clé précédente.

La combinaison du nom csp et du nom du conteneur de clés identifie de manière unique une seule clé sur le système. Si une application tente de modifier un conteneur de clés alors qu’une autre application l’utilise, un comportement imprévisible peut en résulter.

Si vous définissez le paramètre pszContainer sur NULL, le nom du conteneur de clé par défaut est utilisé. Lorsque les fournisseurs de solutions cloud de logiciel Microsoft sont appelés de cette manière, un nouveau conteneur est créé chaque fois que la fonction CryptAcquireContext est appelée. Toutefois, les différents fournisseurs de services partagés peuvent se comporter différemment à cet égard. En particulier, un fournisseur de solutions cloud peut avoir un seul conteneur par défaut partagé par toutes les applications qui accèdent au fournisseur de solutions cloud. Par conséquent, les applications ne doivent pas utiliser le conteneur de clés par défaut pour stocker des clés privées. Au lieu de cela, empêchez le stockage de clés en transmettant l’indicateur CRYPT_VERIFYCONTEXT dans le paramètre dwFlags , ou utilisez un conteneur spécifique à l’application qui est peu susceptible d’être utilisé par une autre application.

Une application peut obtenir le nom du conteneur de clé utilisé à l’aide de la fonction CryptGetProvParam pour lire la valeur PP_CONTAINER.

Pour des raisons de performances, nous vous recommandons de définir le paramètre pszContainer sur NULL et le paramètre dwFlags sur CRYPT_VERIFYCONTEXT dans toutes les situations où vous n’avez pas besoin d’une clé persistante. En particulier, envisagez de définir le paramètre pszContainer sur NULL et le paramètre dwFlags sur CRYPT_VERIFYCONTEXT pour les scénarios suivants :

  • Vous créez un hachage.
  • Vous générez une clé symétrique pour chiffrer ou déchiffrer des données.
  • Vous dérivez une clé symétrique à partir d’un hachage pour chiffrer ou déchiffrer des données.
  • Vous vérifiez une signature. Il est possible d’importer une clé publique à partir d’un PUBLICKEYBLOB ou d’un certificat à l’aide de CryptImportKey ou de CryptImportPublicKeyInfo. Un contexte peut être acquis à l’aide de l’indicateur CRYPT_VERIFYCONTEXT si vous envisagez uniquement d’importer la clé publique.
  • Vous envisagez d’exporter une clé symétrique, mais pas de l’importer dans la durée de vie du contexte de chiffrement. Un contexte peut être acquis à l’aide de l’indicateur CRYPT_VERIFYCONTEXT si vous envisagez uniquement d’importer la clé publique pour les deux derniers scénarios.
  • Vous effectuez des opérations de clé privée, mais vous n’utilisez pas de clé privée persistante stockée dans un conteneur de clés.
Si vous envisagez d’effectuer des opérations de clé privée, la meilleure façon d’acquérir un contexte est d’essayer d’ouvrir le conteneur. Si cette tentative échoue avec NTE_BAD_KEYSET, créez le conteneur à l’aide de l’indicateur CRYPT_NEWKEYSET .

Exemples

L’exemple suivant montre l’acquisition d’un contexte de chiffrement et l’accès à des paires de clés publiques/privées dans un conteneur de clés. Si le conteneur de clé demandé n’existe pas, il est créé.

Pour obtenir un exemple qui inclut le contexte complet de cet exemple, consultez Exemple de programme C : création d’un conteneur de clés et génération de clés. Pour obtenir d’autres exemples, consultez Exemple de programme C : utilisation de 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");
}

Notes

L’en-tête wincrypt.h définit CryptAcquireContext comme un alias qui sélectionne automatiquement la version ANSI ou Unicode de cette fonction en fonction de la définition de la constante de préprocesseur UNICODE. Le mélange de l’utilisation de l’alias neutre en encodage avec du code qui n’est pas neutre en encodage peut entraîner des incompatibilités qui entraînent des erreurs de compilation ou d’exécution. Pour plus d’informations, consultez Conventions pour les prototypes de fonction.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows XP [applications de bureau uniquement]
Serveur minimal pris en charge Windows Server 2003 [applications de bureau uniquement]
Plateforme cible Windows
En-tête wincrypt.h
Bibliothèque Advapi32.lib
DLL Advapi32.dll

Voir aussi

CryptGenKey

CryptGetProvParam

CryptReleaseContext

Fonctions du fournisseur de services

Problèmes de threading avec les fournisseurs de services de chiffrement