

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# API Kriptografi: Generasi Berikutnya (CNG) dan penyedia penyimpanan kunci (KSP) untuk AWS CloudHSM
<a name="ksp-v3-library"></a>

 AWS CloudHSM Klien untuk Windows termasuk penyedia CNG dan KSP.

*Penyedia penyimpanan kunci* (KSPs) mengaktifkan penyimpanan dan pengambilan kunci. Sebagai contoh, jika Anda menambahkan peran Microsoft Active Directory Certificate Services (AD CS) ke server Windows dan memilih untuk membuat kunci privat baru untuk otoritas sertifikat (CA), Anda dapat memilih KSP yang akan mengelola penyimpanan kunci. Bila Anda mengonfigurasi peran AD CS, Anda dapat memilih KSP ini. Untuk informasi selengkapnya, lihat [Buat Windows Server CA](win-ca-overview-sdk5.md#win-ca-setup-sdk5). 

*API Kriptografi: Next Generation (CNG)* adalah API kriptografi khusus untuk sistem operasi Microsoft Windows. CNG mengizinkan developer untuk menggunakan teknik kriptografi untuk mengamankan aplikasi berbasis Windows. Pada tingkat tinggi, AWS CloudHSM implementasi CNG menyediakan fungsionalitas berikut: 
+ **Primitif Kriptografi** — memungkinkan Anda melakukan operasi kriptografi mendasar.
+ **Kunci Impor dan Ekspor** - memungkinkan Anda untuk mengimpor dan mengekspor kunci asimetris.
+ **Data Protection API (CNG DPAPI)** — memungkinkan Anda untuk dengan mudah mengenkripsi dan mendekripsi data.
+ **Key Storage and Retrieval** -—memungkinkan Anda untuk menyimpan dan mengisolasi kunci pribadi dari symmetric key pair dengan aman.

**Topics**
+ [Verifikasi Penyedia KSP dan CNG untuk AWS CloudHSM](ksp-v3-library-install.md)
+ [Prasyarat untuk menggunakan Klien Windows AWS CloudHSM](ksp-library-prereq.md)
+ [Kaitkan AWS CloudHSM kunci dengan sertifikat](ksp-library-associate-key-certificate.md)
+ [Contoh kode untuk penyedia CNG untuk AWS CloudHSM](ksp-library-sample.md)

# Verifikasi Penyedia KSP dan CNG untuk AWS CloudHSM
<a name="ksp-v3-library-install"></a>

Penyedia KSP dan CNG diinstal ketika Anda menginstal klien Windows AWS CloudHSM . Anda dapat menginstal klien dengan mengikuti langkah-langkah di [Instal klien (Windows)](kmu-install-and-configure-client-win.md). 

Gunakan bagian berikut untuk memverifikasi pemasangan penyedia.

## Konfigurasikan dan jalankan AWS CloudHSM klien Windows
<a name="ksp-configure-client-windows"></a>

Untuk memulai klien CloudHSM Windows, Anda harus terlebih dahulu memenuhi [Prasyarat](ksp-library-prereq.md). Kemudian, perbarui file konfigurasi yang digunakan penyedia dan mulai klien dengan menyelesaikan langkah-langkah di bawah ini. Anda perlu melakukan langkah-langkah ini saat pertama kali Anda menggunakan penyedia KSP dan CNG dan setelah Anda menambah atau menghapus HSMs di cluster Anda. Dengan cara AWS CloudHSM ini, mampu menyinkronkan data dan menjaga konsistensi HSMs di semua cluster.

### Langkah 1: Hentikan AWS CloudHSM klien
<a name="ksp-stop-cloudhsm-client"></a>

Sebelum Anda memperbarui file konfigurasi yang digunakan penyedia, hentikan AWS CloudHSM klien. Jika klien sudah berhenti, menjalankan perintah stop tidak berpengaruh. 
+ Untuk klien Windows 1.1.2\$1:

  ```
  C:\Program Files\Amazon\CloudHSM>net.exe stop AWSCloudHSMClient
  ```
+ Untuk klien Windows 1.1.1 dan yang lebih lama:

  Gunakan ****Ctrl\$1C**** di jendela perintah tempat Anda memulai klien. AWS CloudHSM 

### Langkah 2: Perbarui file AWS CloudHSM konfigurasi
<a name="ksp-config-a"></a>

Langkah ini menggunakan `-a` parameter [alat Configure](configure-tool.md) untuk menambahkan alamat IP elastic network interface (ENI) dari salah satu HSMs di cluster ke file konfigurasi. 

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

Untuk mendapatkan alamat IP ENI dari HSM di cluster Anda, navigasikan ke AWS CloudHSM konsol, pilih **cluster**, dan pilih cluster yang diinginkan. Anda juga dapat menggunakan [DescribeClusters](https://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters.html)operasi, [perintah deskripsi-cluster](https://docs.aws.amazon.com/cli/latest/reference/cloudhsmv2/describe-clusters.html), atau cmdlet. [Get-HSM2Cluster](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-HSM2Cluster.html) PowerShell Ketik hanya satu alamat IP ENI. Apa pun alamat IP ENI yang Anda gunakan. 

### Langkah 3: Mulai AWS CloudHSM klien
<a name="ksp-start-cloudhsm-client"></a>

Selanjutnya, mulai atau mulai ulang AWS CloudHSM klien. Ketika AWS CloudHSM klien mulai, ia menggunakan alamat IP ENI dalam file konfigurasi untuk query cluster. Kemudian menambahkan alamat IP ENI dari semua HSMs di cluster ke file informasi cluster. 
+ Untuk klien Windows 1.1.2\$1:

  ```
  C:\Program Files\Amazon\CloudHSM>net.exe start AWSCloudHSMClient
  ```
+ Untuk klien Windows 1.1.1 dan yang lebih lama:

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

## Memeriksa penyedia KSP dan CNG
<a name="ksp-check-providers"></a>

Anda dapat menggunakan salah satu dari perintah berikut untuk menentukan penyedia yang diinstal pada sistem Anda. Perintah daftar penyedia KSP dan CNG terdaftar. Parameter klien AWS CloudHSM tidak perlu berjalan. 

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

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

Untuk memverifikasi bahwa penyedia KSP dan CNG diinstal pada instans EC2 Windows Server, Anda akan melihat entri berikut dalam daftar:

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

Jika penyedia CNG hilang, jalankan perintah berikut. 

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

Jika penyedia KSP hilang, jalankan perintah berikut.

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

# Prasyarat untuk menggunakan Klien Windows AWS CloudHSM
<a name="ksp-library-prereq"></a>

Sebelum Anda dapat memulai AWS CloudHSM klien Windows dan menggunakan penyedia KSP dan CNG, Anda harus mengatur kredensi login untuk HSM di sistem Anda. Anda dapat mengatur kredensial melalui Windows Credential Manager atau variabel lingkungan sistem. Kami sarankan Anda menggunakan Windows Credential Manager untuk menyimpan kredensial. Opsi ini tersedia dengan versi AWS CloudHSM klien 2.0.4 dan yang lebih baru. Menggunakan variabel lingkungan lebih mudah untuk mengatur, tapi kurang aman daripada menggunakan Windows Credential Manager.

## Pengelola Kredensional Windows
<a name="wcm"></a>

Anda dapat menggunakan utilitas `set_cloudhsm_credentials` atau antarmuka Windows Credentials Manager.
+ **Menggunakan utilitas `set_cloudhsm_credentials`**:

  Utilitas `set_cloudhsm_credentials` disertakan dalam penginstal Windows Anda. Anda dapat menggunakan utilitas ini untuk dengan mudah melewati kredensial login HSM ke Windows Credential Manager. Jika Anda ingin mengompilasi utilitas ini dari sumber, Anda dapat menggunakan kode Python yang disertakan dalam installer.

  1. Pergi ke folder `C:\Program Files\Amazon\CloudHSM\tools\`.

  1. Jalankan file `set_cloudhsm_credentials.exe` dengan parameter nama pengguna dan kata sandi CU.

     ```
     set_cloudhsm_credentials.exe --username <CU USER> --password <CU PASSWORD>
     ```
+ **Menggunakan antarmuka Credential Manager**:

  Anda dapat menggunakan antarmuka Credential Manager untuk mengelola kredensial Anda secara manual.

  1. Untuk membuka Credential Manager, ketik `credential manager` di kotak pencarian pada bilah tugas dan pilih**Credential Manager**.

  1. Pilih **Kredensial Windows** untuk mengelola kredensial Windows.

  1. Pilih **Tambah kredensial generik** dan isi detail sebagai berikut:
     + Di **Alamat Internet atau Jaringan**, masukkan nama target sebagai `cloudhsm_client`.
     + Di **Nama pengguna** dan **Kata Sandi**, masukkan kredensial CU.
     + Klik **OK**.

## Variabel lingkungan sistem
<a name="enviorn-var"></a>

Anda dapat mengatur variabel lingkungan sistem yang mengidentifikasi HSM dan [pengguna kripto](understanding-users-cmu.md#crypto-user-cmu) (CU) untuk aplikasi Windows Anda. Anda dapat menggunakan [perintah **setx**](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/setx) untuk mengatur variabel lingkungan sistem, atau mengatur variabel lingkungan sistem permanen [secara terprogram](https://msdn.microsoft.com/en-us/library/system.environment.setenvironmentvariable(v=vs.110).aspx) atau di tab **Lanjutan** dari Panel Kontrol Windows **Properti Sistem**. 

**Awas**  
Ketika Anda mengatur kredensial melalui variabel lingkungan sistem, kata sandi tersedia dalam teks terang pada sistem pengguna. Untuk mengatasi masalah ini, gunakan Windows Credential Manager.

Atur variabel lingkungan sistem berikut:

**`n3fips_password=<CU USERNAME>:<CU PASSWORD>`**  
Mengidentifikasi [pengguna kripto](understanding-users-cmu.md#crypto-user-cmu) (CU) di HSM dan menyediakan semua informasi login yang diperlukan. Aplikasi Anda mengautentikasi dan berjalan sebagai CU ini. Aplikasi memiliki izin CU ini dan dapat melihat dan mengelola hanya kunci yang CU miliki dan bagikan. Untuk membuat CU baru, gunakan [createUser](cloudhsm_mgmt_util-createUser.md). Untuk menemukan yang ada CUs, gunakan [ListUsers](cloudhsm_mgmt_util-listUsers.md).  
Contoh:  

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

# Kaitkan AWS CloudHSM kunci dengan sertifikat
<a name="ksp-library-associate-key-certificate"></a>

Sebelum Anda dapat menggunakan AWS CloudHSM kunci dengan alat pihak ketiga, seperti Microsoft [SignTool](https://docs.microsoft.com/en-us/windows/win32/seccrypto/signtool), Anda harus mengimpor metadata kunci ke toko sertifikat lokal dan mengaitkan metadata dengan sertifikat. Untuk mengimpor metadata kunci, gunakan utilitas import\$1key.exe yang termasuk dalam CloudHSM versi 3.0 dan lebih tinggi. Langkah-langkah berikut memberikan informasi tambahan, dan contoh output.

## Langkah 1: Impor sertifikat Anda
<a name="import-cert"></a>

Pada Windows, Anda akan dapat mengeklik dua kali sertifikat untuk mengimpornya ke penyimpanan sertifikat lokal Anda. 

Namun, jika klik dua kali tidak bekerja, gunakan [alat Microsoft Certreq](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/dn296456%28v%3dws.11%29) untuk mengimpor sertifikat ke certificate manager. Sebagai contoh: 

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

Jika tindakan ini gagal dan Anda menerima kesalahan, `Key not found`, lanjutkan ke Langkah 2. Jika sertifikat muncul di penyimpanan kunci Anda, Anda telah menyelesaikan tugas dan tidak diperlukan tindakan lebih lanjut.

## Langkah 2: Kumpulkan informasi pengenal sertifikat
<a name="cert-identifier"></a>

Jika langkah sebelumnya tidak berhasil, Anda harus mengaitkan kunci privat Anda dengan sertifikat. Namun, sebelum Anda dapat membuat kaitan, Anda harus terlebih dahulu menemukan Nama Kontainer Unik dan Nomor Seri sertifikat . Gunakan utilitas, seperti**certutil**, untuk menampilkan informasi sertifikat yang diperlukan. Output sampel berikut dari **certutil** menunjukkan nama wadah dan nomor seri.

```
================ 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
```



## Langkah 3: Kaitkan kunci AWS CloudHSM pribadi dengan sertifikat
<a name="associate-key-certificate"></a>

Untuk mengaitkan kunci dengan sertifikat, pertama-tama pastikan untuk [memulai daemon AWS CloudHSM klien](key_mgmt_util-setup.md#key_mgmt_util-start-cloudhsm-client). Kemudian, gunakan import\$1key.exe (yang termasuk dalam CloudHSM versi 3.0 dan lebih tinggi) untuk mengaitkan kunci privat dengan sertifikat. Saat menentukan sertifikat, gunakan nama kontainernya yang sederhana. Contoh berikut menunjukkan perintah dan respons. Tindakan ini hanya menyalin metadata kunci; kunci tetap pada HSM.

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

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

## Langkah 4: Perbarui penyimpanan sertifikat
<a name="update-certificate-store"></a>

Pastikan daemon AWS CloudHSM klien masih berjalan. Kemudian, gunakan **certutil** kata kerja,**-repairstore**, untuk memperbarui nomor seri sertifikat. Sampel berikut menunjukkan perintah dan output. Lihat dokumentasi Microsoft untuk informasi tentang [**-repairstore**kata kerja](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.
```

Setelah memperbarui nomor seri sertifikat, Anda dapat menggunakan sertifikat ini dan kunci AWS CloudHSM pribadi yang sesuai dengan alat penandatanganan pihak ketiga di Windows.

# Contoh kode untuk penyedia CNG untuk AWS CloudHSM
<a name="ksp-library-sample"></a>

****  
\$1\$1 Contoh kode saja - Tidak untuk penggunaan produksi\$1\$1  
Kode contoh hanya untuk tujuan ilustrasi. Jangan jalankan kode ini dalam produksi.

Contoh berikut menunjukkan cara menghitung penyedia kriptografi terdaftar pada sistem Anda untuk menemukan penyedia CNG yang diinstal dengan klien CloudHSM untuk Windows. Sampel juga menunjukkan cara membuat pasangan kunci asimetris dan bagaimana menggunakan pasangan kunci untuk menandatangani data. 

**penting**  
Sebelum Anda menjalankan contoh ini, Anda harus mengatur kredensial HSM seperti yang dijelaskan dalam prasyarat. Untuk detailnya, lihat [Prasyarat untuk menggunakan Klien Windows AWS CloudHSM](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;
}
```