CNG 공급자용 코드 예제 - AWS CloudHSM

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

CNG 공급자용 코드 예제

** 예제 코드 전용 - 프로덕션용으로 사용 불가 **

이 예제 코드는 설명을 돕기 위한 참고용일 뿐입니다. 이 코드를 프로덕션용으로 사용하지 마십시오.

다음 예제는 시스템에 등록된 암호화 공급자를 조회하여 Windows용 CloudHSM 클라이언트와 함께 설치된 CNG 공급자를 확인하는 방법을 보여 줍니다. 또한 비대칭 키 페어를 만드는 방법과 키 페어를 사용하여 데이터에 서명하는 방법을 보여 줍니다.

중요

이 예제를 실행하기 전에 사전 조건의 설명에 따라 HSM 자격 증명을 설정해야 합니다. 자세한 내용은 Windows AWS CloudHSM 사전 조건 단원을 참조하세요.

// 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; }