

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# API de cryptographie : fournisseurs de nouvelle génération (CNG) et de stockage de clés (KSP) pour AWS CloudHSM
<a name="ksp-v3-library"></a>

Le AWS CloudHSM client pour Windows inclut les fournisseurs CNG et KSP.

Les *fournisseurs de stockage de clés* (KSPs) permettent le stockage et la récupération des clés. Par exemple, si vous ajoutez le rôle de services de certificats Microsoft Active Directory (AD CS) à votre serveur Windows et choisissez de créer une nouvelle clé privée pour votre autorité de certification (CA), vous pouvez choisir le fournisseur de stockage de clés qui gèrera le stockage. Lorsque vous configurez le rôle AD CS, vous pouvez choisir ce KSP. Pour de plus amples informations, veuillez consulter [Créer une CA Windows Server](win-ca-overview-sdk5.md#win-ca-setup-sdk5). 

*API Cryptography : Next Generation (CNG)* est une API de chiffrement spécifique au système d'exploitation Microsoft Windows. CNG permet aux développeurs d'utiliser les techniques de chiffrement pour sécuriser les applications Windows. À un niveau élevé, la AWS CloudHSM mise en œuvre du GNC fournit les fonctionnalités suivantes : 
+ **Primitives cryptographiques** : elles vous permettent d'effectuer des opérations cryptographiques fondamentales.
+ **Importation et exportation de clés** : vous permet d'importer et d'exporter des clés asymétriques.
+ **API de protection des données (CNG DPAPI)** : vous permet de chiffrer et de déchiffrer facilement les données.
+ **Stockage et récupération des clés** : vous permettent de stocker et d'isoler en toute sécurité la clé privée d'une paire de clés asymétrique.

**Topics**
+ [Vérifiez les fournisseurs KSP et GNC pour AWS CloudHSM](ksp-v3-library-install.md)
+ [Conditions préalables à l'utilisation du client AWS CloudHSM Windows](ksp-library-prereq.md)
+ [Associer une AWS CloudHSM clé à un certificat](ksp-library-associate-key-certificate.md)
+ [Exemple de code pour le fournisseur de GNC pour AWS CloudHSM](ksp-library-sample.md)

# Vérifiez les fournisseurs KSP et GNC pour AWS CloudHSM
<a name="ksp-v3-library-install"></a>

Les fournisseurs KSP et CNG sont installés lorsque vous installez le client Windows AWS CloudHSM . Vous pouvez installer le client en suivant les étapes indiquées dans [Installation du client (Windows)](kmu-install-and-configure-client-win.md). 

Utilisez les sections suivantes pour vérifier l'installation des fournisseurs.

## Configuration et exécution du AWS CloudHSM client Windows
<a name="ksp-configure-client-windows"></a>

Pour démarrer le client Windows CloudHSM, vous devez d'abord respecter les [Conditions préalables](ksp-library-prereq.md). Mettez ensuite à jour les fichiers de configuration utilisés par les fournisseurs et démarrez le client en suivant les étapes ci-dessous. Vous devez effectuer ces étapes la première fois que vous utilisez les fournisseurs KSP et CNG et après avoir ajouté ou supprimé un élément HSMs dans votre cluster. De cette façon, AWS CloudHSM il est possible de synchroniser les données et de maintenir la cohérence HSMs dans l'ensemble du cluster.

### Étape 1 : Arrêter le AWS CloudHSM client
<a name="ksp-stop-cloudhsm-client"></a>

Avant de mettre à jour les fichiers de configuration utilisés par les fournisseurs, arrêtez le AWS CloudHSM client. Si le client est déjà été arrêté, l'exécution de la commande stop n'a aucun effet. 
+ Pour le Client Windows version 1.1.2 et ultérieure :

  ```
  C:\Program Files\Amazon\CloudHSM>net.exe stop AWSCloudHSMClient
  ```
+ Pour les clients Windows version 1.1.1 et antérieure :

  Utilisez **Ctrl** \$1 **C** dans la fenêtre de commande dans laquelle vous avez démarré le AWS CloudHSM client.

### Étape 2 : mise à jour des fichiers AWS CloudHSM de configuration
<a name="ksp-config-a"></a>

Cette étape utilise le `-a` paramètre de l'[outil Configure](configure-tool.md) pour ajouter l'adresse IP ENI (Elastic Network Interface) de l' HSMs un des éléments du cluster au fichier de configuration. 

```
PS C:\> & "C:\Program Files\Amazon\CloudHSM\configure.exe" -a <HSM ENI IP>
```

Pour obtenir l'adresse IP ENI d'un HSM de votre cluster, accédez à la AWS CloudHSM console, choisissez des **clusters**, puis sélectionnez le cluster souhaité. Vous pouvez également utiliser l'[DescribeClusters](https://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters.html)opération, la commande [describe-clusters](https://docs.aws.amazon.com/cli/latest/reference/cloudhsmv2/describe-clusters.html) ou l'applet de [Get-HSM2Cluster](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-HSM2Cluster.html) PowerShellcommande. Saisissez une seule adresse IP d'ENI. Peu importe l'adresse IP d'ENI que vous utilisez. 

### Étape 3 : démarrer le AWS CloudHSM client
<a name="ksp-start-cloudhsm-client"></a>

Ensuite, démarrez ou redémarrez le AWS CloudHSM client. Lorsque le AWS CloudHSM client démarre, il utilise l'adresse IP ENI dans son fichier de configuration pour interroger le cluster. Il ajoute ensuite les adresses IP ENI de tous HSMs les membres du cluster au fichier d'informations du cluster. 
+ Pour le Client Windows version 1.1.2 et ultérieure :

  ```
  C:\Program Files\Amazon\CloudHSM>net.exe start AWSCloudHSMClient
  ```
+ Pour les clients Windows version 1.1.1 et antérieure :

  ```
  C:\Program Files\Amazon\CloudHSM>start "cloudhsm_client" cloudhsm_client.exe C:\ProgramData\Amazon\CloudHSM\data\cloudhsm_client.cfg
  ```

## Recherche de fournisseurs KSP et GNC
<a name="ksp-check-providers"></a>

Vous pouvez utiliser l'une ou l'autre des commandes suivantes afin de déterminer les fournisseurs qui sont installés sur votre système. Les commandes répertorient les fournisseurs KSP et CNG enregistrée. Le client AWS CloudHSM n'a pas besoin d'être en cours d'exécution. 

```
PS C:\> & "C:\Program Files\Amazon\CloudHSM\ksp_config.exe" -enum
```

```
PS C:\> & "C:\Program Files\Amazon\CloudHSM\cng_config.exe" -enum
```

Pour vérifier que les fournisseurs KSP et CNG sont installés sur votre instance Windows Server EC2, vous devriez voir les entrées suivantes dans la liste :

```
Cavium CNG Provider
Cavium Key Storage Provider
```

Si le fournisseur CNG est manquant, exécutez la commande suivante. 

```
PS C:\> & "C:\Program Files\Amazon\CloudHSM\cng_config.exe" -register
```

Si le fournisseur KSP est manquant, exécutez la commande suivante.

```
PS C:\> & "C:\Program Files\Amazon\CloudHSM\ksp_config.exe" -register
```

# Conditions préalables à l'utilisation du client AWS CloudHSM Windows
<a name="ksp-library-prereq"></a>

Avant de démarrer le AWS CloudHSM client Windows et d'utiliser les fournisseurs KSP et CNG, vous devez définir les informations de connexion du HSM sur votre système. Vous pouvez définir les informations d'identification via le Gestionnaire d'informations d'identification Windows ou la variable d'environnement système. Nous vous recommandons d'utiliser le Gestionnaire d'informations d'identification Windows pour stocker les informations d'identification. Cette option est disponible avec les versions 2.0.4 et ultérieures du AWS CloudHSM client. L'utilisation de la variable d'environnement est plus facile à configurer, mais moins sécurisée que l'utilisation du Gestionnaire d'informations d'identification Windows.

## Gestionnaire d'informations d'identification Windows
<a name="wcm"></a>

Vous pouvez utiliser l'utilitaire `set_cloudhsm_credentials` ou l'interface du Gestionnaire d'informations d'identification Windows.
+ **Utilisation de l'utilitaire `set_cloudhsm_credentials`** :

  L'utilitaire `set_cloudhsm_credentials` est inclus dans votre programme d'installation Windows. Vous pouvez utiliser cet utilitaire pour transmettre facilement les informations d'identification de connexion HSM au Gestionnaire d'informations d'identification Windows. Si vous souhaitez compiler cet utilitaire à partir de la source, vous pouvez utiliser le code Python inclus dans le programme d'installation.

  1. Accédez au dossier `C:\Program Files\Amazon\CloudHSM\tools\`.

  1. Exécutez le fichier `set_cloudhsm_credentials.exe` avec les paramètres de nom d'utilisateur et de mot de passe CU.

     ```
     set_cloudhsm_credentials.exe --username <CU USER> --password <CU PASSWORD>
     ```
+ **Utilisation de l'interface du Gestionnaire d'informations d'identification** :

  Vous pouvez utiliser l'interface du Gestionnaire d'informations d'identification pour gérer manuellement vos informations d'identification.

  1. Pour ouvrir Credential Manager, tapez `credential manager` dans la zone de recherche de la barre des tâches et sélectionnez **Credential Manager (Gestionnaire d'informations d'identification)**.

  1. Sélectionnez **Windows Credentials (Informations d'identification)** pour gérer les informations d'identification Windows.

  1. Sélectionnez **Add a generic credential (Ajouter une information d'identification générique)** et remplissez les détails comme suit :
     + Dans **Internet ou Network Address (Adresse Internet ou réseau)**, entrez le nom de la cible en tant que `cloudhsm_client`.
     + Dans **Username (Nom d'utilisateur)** et **Password (Mot de passe)** entrez les informations d'identification CU.
     + Cliquez sur **OK**.

## Variables d'environnement du système
<a name="enviorn-var"></a>

Vous pouvez définir des variables d'environnement système qui identifient un HSM et un [utilisateur de chiffrement](understanding-users-cmu.md#crypto-user-cmu) (CU) pour votre application Windows. Vous pouvez utiliser la [commande **setx**](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/setx) pour définir des variables d'environnement système temporaires ou pour définir des variables d'environnement système permanentes [par programmation](https://msdn.microsoft.com/en-us/library/system.environment.setenvironmentvariable(v=vs.110).aspx) ou sous l'onglet **Avancé** du Panneau de configuration **Propriétés système** de Windows. 

**Avertissement**  
Lorsque vous définissez des informations d'identification via des variables d'environnement système, le mot de passe est disponible en texte brut sur le système d'un utilisateur. Pour résoudre ce problème, utilisez le Gestionnaire d'informations d'identification Windows.

Définissez les variables d'environnement système suivantes :

**`n3fips_password=<CU USERNAME>:<CU PASSWORD>`**  
Identifie un [utilisateur de chiffrement](understanding-users-cmu.md#crypto-user-cmu) (CU) dans le HSM et fournit toutes les informations de connexion requises. Votre application s'authentifie et s'exécute en tant que ce CU. L'application possède les autorisations de ce CU et peut afficher et gérer uniquement les clés que le CU possède et partage. Pour créer un CU, utilisez [createUser](cloudhsm_mgmt_util-createUser.md). Pour rechercher les fichiers existants CUs, utilisez [ListUsers](cloudhsm_mgmt_util-listUsers.md).  
Par exemple :  

```
setx /m n3fips_password test_user:password123
```

# Associer une AWS CloudHSM clé à un certificat
<a name="ksp-library-associate-key-certificate"></a>

Avant de pouvoir utiliser des AWS CloudHSM clés avec des outils tiers, tels que ceux de Microsoft [SignTool](https://docs.microsoft.com/en-us/windows/win32/seccrypto/signtool), vous devez importer les métadonnées de la clé dans le magasin de certificats local et associer les métadonnées à un certificat. Pour importer les métadonnées de la clé, utilisez l'utilitaire import\$1key.exe qui est inclus dans CloudHSM version 3.0 et supérieure. Les étapes suivantes fournissent des informations supplémentaires et un exemple de sortie.

## Étape 1 : Importer votre certificat
<a name="import-cert"></a>

Sous Windows, vous pouvez normalement double-cliquer sur le certificat pour l'importer dans votre magasin de certificats local. 

Toutefois, si un double-clic ne fonctionne pas, utilisez l'[outil Microsoft Certreq](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/dn296456%28v%3dws.11%29) pour importer le certificat dans le gestionnaire de certificats. Par exemple : 

```
certreq -accept <certificatename>
```

Si cette action échoue et que vous recevez l'erreur `Key not found`, passez à l'étape 2. Si le certificat apparaît dans votre magasin de clés, vous avez terminé la tâche et aucune autre action n'est nécessaire.

## Étape 2 : Recueillir des renseignements permettant d'identifier les certificats
<a name="cert-identifier"></a>

Si l'étape précédente n'a pas réussi, vous devrez associer votre clé privée à un certificat. Toutefois, avant de pouvoir créer l'association, vous devez d'abord trouver le nom de conteneur unique et le numéro de série du certificat. Utilisez un utilitaire, tel que**certutil**, pour afficher les informations de certificat requises. L'exemple de sortie suivant **certutil** indique le nom du conteneur et le numéro de série.

```
================ Certificate 1 ================ Serial Number:
			72000000047f7f7a9d41851b4e000000000004Issuer: CN=Enterprise-CANotBefore: 10/8/2019 11:50
			AM NotAfter: 11/8/2020 12:00 PMSubject: CN=www.example.com, OU=Certificate Management,
			O=Information Technology, L=Seattle, S=Washington, C=USNon-root CertificateCert
			Hash(sha1): 7f d8 5c 00 27 bf 37 74 3d 71 5b 54 4e c0 94 20 45 75 bc 65No key provider
			information Simple container name: CertReq-39c04db0-6aa9-4310-93db-db0d9669f42c Unique
			container name: CertReq-39c04db0-6aa9-4310-93db-db0d9669f42c
```



## Étape 3 : associer la clé AWS CloudHSM privée au certificat
<a name="associate-key-certificate"></a>

Pour associer la clé au certificat, assurez-vous d'abord de [démarrer le daemon AWS CloudHSM client](key_mgmt_util-setup.md#key_mgmt_util-start-cloudhsm-client). Ensuite, utilisez import\$1key.exe (qui est inclus dans CloudHSM version 3.0 et supérieure) pour associer la clé privée au certificat. Lorsque vous spécifiez le certificat, utilisez son nom de conteneur simple. L'exemple suivant montre la commande et la réponse. Cette action copie uniquement les métadonnées de la clé ; la clé reste sur le HSM.

```
$> import_key.exe –RSA CertReq-39c04db0-6aa9-4310-93db-db0d9669f42c

Successfully opened Microsoft Software Key Storage Provider : 0NCryptOpenKey failed : 80090016
```

## Étape 4 : Mettre à jour le magasin de certificats
<a name="update-certificate-store"></a>

Assurez-vous que le démon AWS CloudHSM client est toujours en cours d'exécution. Utilisez ensuite le **certutil** verbe**-repairstore**, pour mettre à jour le numéro de série du certificat. L'exemple suivant montre la commande et la sortie. Consultez la documentation Microsoft pour plus d'informations sur le [**-repairstore**verbe](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc732443(v=ws.11)?redirectedfrom=MSDN#-repairstore).

```
C:\Program Files\Amazon\CloudHSM>certutil -f -csp "Cavium Key Storage Provider"-repairstore my "72000000047f7f7a9d41851b4e000000000004"
my "Personal"
================ Certificate 1 ================
Serial Number: 72000000047f7f7a9d41851b4e000000000004
Issuer: CN=Enterprise-CA
NotBefore: 10/8/2019 11:50 AM
NotAfter: 11/8/2020 12:00 PM
Subject: CN=www.example.com, OU=Certificate Management, O=Information Technology, L=Seattle, S=Washington, C=US
Non-root CertificateCert Hash(sha1): 7f d8 5c 00 27 bf 37 74 3d 71 5b 54 4e c0 94 20 45 75 bc 65       
SDK Version: 3.0 
Key Container = CertReq-39c04db0-6aa9-4310-93db-db0d9669f42c 
Provider = "Cavium Key Storage Provider"
Private key is NOT exportableEncryption test passedCertUtil: -repairstore command completed successfully.
```

Après avoir mis à jour le numéro de série du certificat, vous pouvez utiliser ce certificat et la clé AWS CloudHSM privée correspondante avec n'importe quel outil de signature tiers sous Windows.

# Exemple de code pour le fournisseur de GNC pour AWS CloudHSM
<a name="ksp-library-sample"></a>

****  
\$1\$1 Exemple de code uniquement — Non destiné à une utilisation en production \$1\$1  
Cet exemple de code est donné uniquement à titre d'illustration. N'exécutez pas ce code dans un environnement de production.

L'exemple suivant montre comment énumérer les fournisseurs de chiffrement enregistrés dans votre système pour trouver le fournisseur CNG installé avec le client CloudHSM pour Windows. L'exemple montre également comment créer une paire de clés asymétrique et comment utiliser la paire de clés pour vous signer les données. 

**Important**  
Avant d'exécuter cet exemple, vous devez configurer les informations d'identification HSM comme expliqué dans les prérequis. Pour en savoir plus, consultez [Conditions préalables à l'utilisation du client AWS CloudHSM Windows](ksp-library-prereq.md). 

```
// CloudHsmCngExampleConsole.cpp : Console application that demonstrates CNG capabilities.
// This example contains the following functions.
//
//   VerifyProvider()          - Enumerate the registered providers and retrieve Cavium KSP and CNG providers.
//   GenerateKeyPair()         - Create an RSA key pair.
//   SignData()                - Sign and verify data.
//

#include "stdafx.h"
#include <Windows.h>

#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif

#define CAVIUM_CNG_PROVIDER L"Cavium CNG Provider"
#define CAVIUM_KEYSTORE_PROVIDER L"Cavium Key Storage Provider"

// Enumerate the registered providers and determine whether the Cavium CNG provider
// and the Cavium KSP provider exist.
//
bool VerifyProvider()
{
  NTSTATUS status;
  ULONG cbBuffer = 0;
  PCRYPT_PROVIDERS pBuffer = NULL;
  bool foundCng = false;
  bool foundKeystore = false;

  // Retrieve information about the registered providers.
  //   cbBuffer - the size, in bytes, of the buffer pointed to by pBuffer.
  //   pBuffer - pointer to a buffer that contains a CRYPT_PROVIDERS structure.
  status = BCryptEnumRegisteredProviders(&cbBuffer, &pBuffer);

  // If registered providers exist, enumerate them and determine whether the
  // Cavium CNG provider and Cavium KSP provider have been registered.
  if (NT_SUCCESS(status))
  {
    if (pBuffer != NULL)
    {
      for (ULONG i = 0; i < pBuffer->cProviders; i++)
      {
        // Determine whether the Cavium CNG provider exists.
        if (wcscmp(CAVIUM_CNG_PROVIDER, pBuffer->rgpszProviders[i]) == 0)
        {
          printf("Found %S\n", CAVIUM_CNG_PROVIDER);
          foundCng = true;
        }

        // Determine whether the Cavium KSP provider exists.
        else if (wcscmp(CAVIUM_KEYSTORE_PROVIDER, pBuffer->rgpszProviders[i]) == 0)
        {
          printf("Found %S\n", CAVIUM_KEYSTORE_PROVIDER);
          foundKeystore = true;
        }
      }
    }
  }
  else
  {
    printf("BCryptEnumRegisteredProviders failed with error code 0x%08x\n", status);
  }

  // Free memory allocated for the CRYPT_PROVIDERS structure.
  if (NULL != pBuffer)
  {
    BCryptFreeBuffer(pBuffer);
  }

  return foundCng == foundKeystore == true;
}

// Generate an asymmetric key pair. As used here, this example generates an RSA key pair 
// and returns a handle. The handle is used in subsequent operations that use the key pair. 
// The key material is not available.
//
// The key pair is used in the SignData function.
//
NTSTATUS GenerateKeyPair(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE *hKey)
{
  NTSTATUS status;

  // Generate the key pair.
  status = BCryptGenerateKeyPair(hAlgorithm, hKey, 2048, 0);
  if (!NT_SUCCESS(status))
  {
    printf("BCryptGenerateKeyPair failed with code 0x%08x\n", status);
    return status;
  }

  // Finalize the key pair. The public/private key pair cannot be used until this 
  // function is called.
  status = BCryptFinalizeKeyPair(*hKey, 0);
  if (!NT_SUCCESS(status))
  {
    printf("BCryptFinalizeKeyPair failed with code 0x%08x\n", status);
    return status;
  }

  return status;
}

// Sign and verify data using the RSA key pair. The data in this function is hardcoded
// and is for example purposes only.
//
NTSTATUS SignData(BCRYPT_KEY_HANDLE hKey)
{
  NTSTATUS status;
  PBYTE sig;
  ULONG sigLen;
  ULONG resLen;
  BCRYPT_PKCS1_PADDING_INFO pInfo;

  // Hardcode the data to be signed (for demonstration purposes only).
  PBYTE message = (PBYTE)"d83e7716bed8a20343d8dc6845e57447";
  ULONG messageLen = strlen((char*)message);

  // Retrieve the size of the buffer needed for the signature.
  status = BCryptSignHash(hKey, NULL, message, messageLen, NULL, 0, &sigLen, 0);
  if (!NT_SUCCESS(status))
  {
    printf("BCryptSignHash failed with code 0x%08x\n", status);
    return status;
  }

  // Allocate a buffer for the signature.
  sig = (PBYTE)HeapAlloc(GetProcessHeap(), 0, sigLen);
  if (sig == NULL)
  {
    return -1;
  }

  // Use the SHA256 algorithm to create padding information.
  pInfo.pszAlgId = BCRYPT_SHA256_ALGORITHM;

  // Create a signature.
  status = BCryptSignHash(hKey, &pInfo, message, messageLen, sig, sigLen, &resLen, BCRYPT_PAD_PKCS1);
  if (!NT_SUCCESS(status))
  {
    printf("BCryptSignHash failed with code 0x%08x\n", status);
    return status;
  }

  // Verify the signature.
  status = BCryptVerifySignature(hKey, &pInfo, message, messageLen, sig, sigLen, BCRYPT_PAD_PKCS1);
  if (!NT_SUCCESS(status))
  {
    printf("BCryptVerifySignature failed with code 0x%08x\n", status);
    return status;
  }

  // Free the memory allocated for the signature.
  if (sig != NULL)
  {
    HeapFree(GetProcessHeap(), 0, sig);
    sig = NULL;
  }

  return 0;
}

// Main function.
//
int main()
{
  NTSTATUS status;
  BCRYPT_ALG_HANDLE hRsaAlg;
  BCRYPT_KEY_HANDLE hKey = NULL;

  // Enumerate the registered providers.
  printf("Searching for Cavium providers...\n");
  if (VerifyProvider() == false) {
    printf("Could not find the CNG and Keystore providers\n");
    return 1;
  }

  // Get the RSA algorithm provider from the Cavium CNG provider.
  printf("Opening RSA algorithm\n");
  status = BCryptOpenAlgorithmProvider(&hRsaAlg, BCRYPT_RSA_ALGORITHM, CAVIUM_CNG_PROVIDER, 0);
  if (!NT_SUCCESS(status))
  {
    printf("BCryptOpenAlgorithmProvider RSA failed with code 0x%08x\n", status);
    return status;
  }

  // Generate an asymmetric key pair using the RSA algorithm.
  printf("Generating RSA Keypair\n");
  GenerateKeyPair(hRsaAlg, &hKey);
  if (hKey == NULL)
  {
    printf("Invalid key handle returned\n");
    return 0;
  }
  printf("Done!\n");

  // Sign and verify [hardcoded] data using the RSA key pair.
  printf("Sign/Verify data with key\n");
  SignData(hKey);
  printf("Done!\n");

  // Remove the key handle from memory.
  status = BCryptDestroyKey(hKey);
  if (!NT_SUCCESS(status))
  {
    printf("BCryptDestroyKey failed with code 0x%08x\n", status);
    return status;
  }

  // Close the RSA algorithm provider.
  status = BCryptCloseAlgorithmProvider(hRsaAlg, NULL);
  if (!NT_SUCCESS(status))
  {
    printf("BCryptCloseAlgorithmProvider RSA failed with code 0x%08x\n", status);
    return status;
  }

  return 0;
}
```