win10枚举所有证书服务提供者CSP和获取默认CSP

简介

微软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    
#include    
#include    
#include    
//-------------------------------------------------------------------   
// 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();
} 

运行截图

win10枚举所有证书服务提供者CSP和获取默认CSP_第1张图片

你可能感兴趣的:(windows操作系统,C/C++应用,windows,visual,studio,c++)