예제 C 프로그램: 키 컨테이너 만들기 및 키 생성
다음 예제에서는 명명된 키 컨테이너 를 만들고 서명 키 쌍 과 교환 키 쌍 을 컨테이너에 추가합니다. 명명된 키 컨테이너와 암호화 키가 이미 있는 경우에도 이 예제를 문제 없이 실행할 수 있습니다.
참고
애플리케이션은 기본 키 컨테이너를 사용하여 프라이빗 키를 저장해서는 안 됩니다. 여러 애플리케이션이 동일한 컨테이너를 사용하는 경우 한 애플리케이션이 다른 애플리케이션에서 사용할 수 있어야 하는 키를 변경하거나 삭제할 수 있습니다. 애플리케이션은 애플리케이션에 연결된 키 컨테이너를 사용하는 것이 좋습니다. 이렇게 하면 다른 애플리케이션이 제대로 작동하는 데 필요한 키를 변조할 위험이 줄어듭니다.
이 예제에서는 다음 작업 및 CryptoAPI 함수를 보여 줍니다.
- 명명된 키 컨테이너를 획득하려고 시도합니다. 명명된 키 컨테이너가 아직 없으면 만들어집니다.
- 키 컨테이너에 서명 키 쌍이 없는 경우 키 컨테이너 내에 서명 키 쌍을 만듭니다.
- 키 컨테이너에 Exchange 키 쌍이 없는 경우 키 컨테이너 내에 교환 키 쌍을 만듭니다.
이러한 작업은 각 컴퓨터의 각 사용자에 대해 한 번만 수행하면 됩니다. 명명된 키 컨테이너 및 키 쌍이 이미 만들어진 경우 이 샘플은 작업을 수행하지 않습니다.
이 예제에서는 다음 CryptoAPI 함수를 사용합니다.
이 예제에서는 MyHandleError 함수를 사용합니다. 이 함수의 코드는 샘플에 포함되어 있습니다. 이 함수 및 기타 보조 함수에 대한 코드도 범용 함수 아래에 나열됩니다.
//-------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
#pragma comment(lib, "crypt32.lib")
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <Wincrypt.h>
//-------------------------------------------------------------------
// This example uses the function MyHandleError, a simple error
// handling function to print an error message and exit
// the program.
// For most applications, replace this function with one
// that does more extensive error reporting.
void MyHandleError(LPTSTR psz)
{
_ftprintf(stderr, TEXT("An error occurred in the program. \n"));
_ftprintf(stderr, TEXT("%s\n"), psz);
_ftprintf(stderr, TEXT("Error number %x.\n"), GetLastError());
_ftprintf(stderr, TEXT("Program terminating. \n"));
exit(1);
} // End of MyHandleError.
void main(void)
{
// Handle for the cryptographic provider context.
HCRYPTPROV hCryptProv;
// The name of the container.
LPCTSTR pszContainerName = TEXT("My Sample Key Container");
//---------------------------------------------------------------
// Begin processing. Attempt to acquire a context by using the
// specified key container.
if(CryptAcquireContext(
&hCryptProv,
pszContainerName,
NULL,
PROV_RSA_FULL,
0))
{
_tprintf(
TEXT("A crypto context with the %s key container ")
TEXT("has been acquired.\n"),
pszContainerName);
}
else
{
//-----------------------------------------------------------
// Some sort of error occurred in acquiring the context.
// This is most likely due to the specified container
// not existing. Create a new key container.
if(GetLastError() == NTE_BAD_KEYSET)
{
if(CryptAcquireContext(
&hCryptProv,
pszContainerName,
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
_tprintf(TEXT("A new key container has been ")
TEXT("created.\n"));
}
else
{
MyHandleError(TEXT("Could not create a new key ")
TEXT("container.\n"));
}
}
else
{
MyHandleError(TEXT("CryptAcquireContext failed.\n"));
}
}
//---------------------------------------------------------------
// A context with a key container is available.
// Attempt to get the handle to the signature key.
// Public/private key handle.
HCRYPTKEY hKey;
if(CryptGetUserKey(
hCryptProv,
AT_SIGNATURE,
&hKey))
{
_tprintf(TEXT("A signature key is available.\n"));
}
else
{
_tprintf(TEXT("No signature key is available.\n"));
if(GetLastError() == NTE_NO_KEY)
{
//-------------------------------------------------------
// The error was that there is a container but no key.
// Create a signature key pair.
_tprintf(TEXT("The signature key does not exist.\n"));
_tprintf(TEXT("Create a signature key pair.\n"));
if(CryptGenKey(
hCryptProv,
AT_SIGNATURE,
0,
&hKey))
{
_tprintf(TEXT("Created a signature key pair.\n"));
}
else
{
MyHandleError(TEXT("Error occurred creating a ")
TEXT("signature key.\n"));
}
}
else
{
MyHandleError(TEXT("An error other than NTE_NO_KEY ")
TEXT("getting a signature key.\n"));
}
} // End if.
_tprintf(TEXT("A signature key pair existed, or one was ")
TEXT("created.\n\n"));
// Destroy the signature key.
if(hKey)
{
if(!(CryptDestroyKey(hKey)))
{
MyHandleError(TEXT("Error during CryptDestroyKey."));
}
hKey = NULL;
}
// Next, check the exchange key.
if(CryptGetUserKey(
hCryptProv,
AT_KEYEXCHANGE,
&hKey))
{
_tprintf(TEXT("An exchange key exists.\n"));
}
else
{
_tprintf(TEXT("No exchange key is available.\n"));
// Check to determine whether an exchange key
// needs to be created.
if(GetLastError() == NTE_NO_KEY)
{
// Create a key exchange key pair.
_tprintf(TEXT("The exchange key does not exist.\n"));
_tprintf(TEXT("Attempting to create an exchange key ")
TEXT("pair.\n"));
if(CryptGenKey(
hCryptProv,
AT_KEYEXCHANGE,
0,
&hKey))
{
_tprintf(TEXT("Exchange key pair created.\n"));
}
else
{
MyHandleError(TEXT("Error occurred attempting to ")
TEXT("create an exchange key.\n"));
}
}
else
{
MyHandleError(TEXT("An error other than NTE_NO_KEY ")
TEXT("occurred.\n"));
}
}
// Destroy the exchange key.
if(hKey)
{
if(!(CryptDestroyKey(hKey)))
{
MyHandleError(TEXT("Error during CryptDestroyKey."));
}
hKey = NULL;
}
// Release the CSP.
if(hCryptProv)
{
if(!(CryptReleaseContext(hCryptProv, 0)))
{
MyHandleError(TEXT("Error during CryptReleaseContext."));
}
}
_tprintf(TEXT("Everything is okay. A signature key "));
_tprintf(TEXT("pair and an exchange key exist in "));
_tprintf(TEXT("the %s key container.\n"), pszContainerName);
} // End main.