简介
微软MSDN上提供的例子,作用是枚举当前操作系统上所有已安装的CSP(证书服务提供者), 并获取系统默认的CSP.
现在在WIN10上还可以正常运行。但是微软貌似不推荐CSP其中的某些API继续使用。未来CNG(下一代加密技术)将成为主主流开发技术,希望开发者慢慢向CNG过度吧。
代码如下
// winrsa.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//-------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. 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 enumproviders();
void getdefaultprovider();
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)
{
enumproviders(); // 枚举系统中安装的csp的名称
printf("%%%%%%%%%%%%%%%\n");
getdefaultprovider(); //获得系统默认的csp
printf("%%%%%%%%%%%%%%%\n");
if(CryptSetProviderEx( //设置系统默认的csp
"Microsoft Strong Cryptographic Provider",
1,
NULL,
CRYPT_MACHINE_DEFAULT
))
printf("successful \n");
else
printf("%d\n", GetLastError());
// Handle for the cryptographic provider context.
HCRYPTPROV hCryptProv;
// The name of the container.
LPCTSTR pszContainerName = TEXT("hope10");
//---------------------------------------------------------------
// 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"));
}
}
DWORD pdatalen = 1024;
BYTE* cspname = (BYTE*)malloc(1024);
CryptGetProvParam(hCryptProv, PP_NAME, cspname, &pdatalen, 0);
printf("******** %s\n", cspname);
//---------------------------------------------------------------
// 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"));
FILE *fp;
fp = fopen("d:\\test.dat", "wb");
fwrite(&hKey, 1, 2048, fp);
fclose(fp);
}
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;
}
// 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.
void enumproviders()
{
//---------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Declare and initialize variables.
DWORD cbName;
DWORD dwType;
DWORD dwIndex;
CHAR *pszName = NULL;
// Print header lines for providers.
printf("Listing Available Providers:\n");
printf("Provider type\tProvider Name\n");
printf("_____________\t__________________"
"___________________\n");
//---------------------------------------------------------------
// Loop through enumerating providers.
dwIndex = 0;
while(CryptEnumProviders(
dwIndex,
NULL,
0,
&dwType,
NULL,
&cbName
))
{
//-----------------------------------------------------------
// cbName returns the length of the name of the next
// provider. Allocate memory in a buffer to retrieve
// that name.
if (!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName)))
{
printf("ERROR - LocalAlloc failed\n");
exit(1);
}
//-----------------------------------------------------------
// Get the provider name.
if (CryptEnumProviders(
dwIndex++,
NULL,
0,
&dwType,
pszName,
&cbName
))
{
printf (" %4.0d\t%s\n",dwType, pszName);
}
else
{
printf("ERROR - CryptEnumProviders failed.\n");
exit(1);
}
LocalFree(pszName);
} // End of while loop
printf("\nProvider types and provider names "
"have been listed.\n");
}
void getdefaultprovider()
{
DWORD cbProvName=0;
LPTSTR pbProvName=NULL;
// Copyright (c) Microsoft Corporation. All rights reserved.
// Get the length of the RSA_FULL default provider name.
if (!(CryptGetDefaultProvider(
PROV_RSA_FULL,
NULL,
CRYPT_MACHINE_DEFAULT,
NULL,
&cbProvName)))
{
printf("Error getting the length of the default "
"provider name.\n");
exit(1);
}
// Allocate local memory for the name of the default provider.
if (!(pbProvName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT,
cbProvName)))
{
printf("Error during memory allocation for "
"provider name.\n");
exit(1);
}
// Get the default provider name.
if (CryptGetDefaultProvider(
PROV_RSA_FULL,
NULL,
CRYPT_MACHINE_DEFAULT,
pbProvName,
&cbProvName))
{
printf("The default provider name is %s\n",pbProvName);
}
else
{
printf("Getting the name of the provider failed.\n");
exit(1);
}
// Free resources when done.
LocalFree(pbProvName);
getchar();
}