範例 C 程式:匯出工作階段金鑰
下列範例會建立隨機工作階段金鑰,並建立可匯出 的金鑰 BLOB。 此範例說明 如何使用 CryptGetUserKey、 CryptExportKey和相關函式。
此範例說明下列工作和 CryptoAPI 函式:
- 使用 CryptAcquireCoNtext取得 CSP 內容。
- 使用 CryptGetUserKey存取兩組不同的公開/私密金鑰。
- 使用 CryptGenKey產生可匯出的工作階段金鑰。
- 使用CryptExportKey建立包含工作階段金鑰的簡單金鑰 BLOB。
- 使用 CryptDestroyKey終結工作階段金鑰,並存取兩對公開/私密金鑰。
- 使用 CryptReleaseCoNtext釋放 CSP 內容。
此範例會使用 MyHandleError函式。 此函式的程式碼隨附于範例中。 此函式和其他輔助函式的程式碼也會列在常規用途 Functions底下。
//--------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// This example program creates a session key and a simple key
// BLOB holding that session key. The key BLOB can be written to disk
// and later read from a disk file.
#pragma comment(lib, "crypt32.lib")
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);
void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.
HCRYPTPROV hProv; // CSP handle
HCRYPTKEY hSignKey; // Signature key pair handle
HCRYPTKEY hXchgKey; // Exchange key pair handle
HCRYPTKEY hKey; // Session key handle
BYTE *pbKeyBlob; // Pointer to a simple key BLOB
DWORD dwBlobLen; // The length of the key BLOB
//--------------------------------------------------------------------
// Acquire a cryptographic provider context handle.
if(CryptAcquireContext(
&hProv,
NULL,
NULL,
PROV_RSA_FULL,
0))
{
printf("The CSP has been acquired. \n");
}
else
{
MyHandleError("Error during CryptAcquireContext.");
}
//--------------------------------------------------------------------
// Get a handle to the signature key.
// The signature key must exist before it can be retrieved. For more
// information, see the CryptGetUserKey documentation.
if(CryptGetUserKey(
hProv,
AT_SIGNATURE,
&hSignKey))
{
printf("The signature key has been acquired. \n");
}
else
{
MyHandleError("Error during CryptGetUserKey for signkey.");
}
//--------------------------------------------------------------------
// Get a handle to the key exchange key.
// The key must exist before it can be retrieved. For more
// information, see the CryptGetUserKey documentation.
if(CryptGetUserKey(
hProv,
AT_KEYEXCHANGE,
&hXchgKey))
{
printf("The key exchange key has been acquired. \n");
}
else
{
printf("Error during CryptGetUserKey exchange key.");
}
// hSignKey may be used to verify a signature. hXchgKey will be used
// to export a session key.
//--------------------------------------------------------------------
// Generate a session key.
if (CryptGenKey(
hProv,
CALG_RC4,
CRYPT_EXPORTABLE,
&hKey))
{
printf("Original session key is created. \n");
}
else
{
MyHandleError("ERROR -- CryptGenKey.");
}
// Determine the size of the key BLOB and allocate memory.
if(CryptExportKey(
hKey,
hXchgKey,
SIMPLEBLOB,
0,
NULL,
&dwBlobLen))
{
printf("Size of the BLOB for the session key determined. \n");
}
else
{
MyHandleError("Error computing BLOB length.");
}
if(pbKeyBlob = (BYTE*)malloc(dwBlobLen))
{
printf("Memory has been allocated for the BLOB. \n");
}
else
{
MyHandleError("Out of memory. \n");
}
//--------------------------------------------------------------------
// Export the key into a simple key BLOB.
if(CryptExportKey(
hKey,
hXchgKey,
SIMPLEBLOB,
0,
pbKeyBlob,
&dwBlobLen))
{
printf("Contents have been written to the BLOB. \n");
}
else
{
MyHandleError("Error during CryptExportKey.");
}
//--------------------------------------------------------------------
// At this point, other processing such as writing the key BLOB to
// a file could be done.
//--------------------------------------------------------------------
// After all processing, clean up.
//--------------------------------------------------------------------
// Free the memory used by the key BLOB.
free(pbKeyBlob);
// Destroy the session key.
if(hKey)
CryptDestroyKey(hKey);
// Destroy the signature key handle.
if(hSignKey)
CryptDestroyKey(hSignKey);
// Destroy the key exchange key handle.
if(hXchgKey)
CryptDestroyKey(hXchgKey);
// Release the provider handle.
if(hProv)
CryptReleaseContext(hProv, 0);
printf("The program ran to completion without error. \n");
}// End of main
//--------------------------------------------------------------------
// 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(char *s)
{
printf("An error occurred in running the program.\n");
printf("%s\n",s);
printf("Error number %x\n.",GetLastError());
printf("Program terminating.\n");
exit(1);
}