zoukankan      html  css  js  c++  java
  • CryptoAPI 学习

    本文由网上各类汇总····

    加密与解密第二版 222 页查看  学习:







    下面的实验顺序颠倒,便于复习```````````````````````````````````````````


    实验9````````````````````````````` 

    CALG_AES_128 但是发现好像加密解密出来不对的感觉 

    #include "stdafx.h"
    #include <stdio.h>
    #include <string>
    #include <iostream>
    #include <windows.h>
    #include <Wincrypt.h>
    #pragma comment (lib, "crypt32.lib")
    
      using namespace std;
    
    void cryptoAPI_encrypt(string text, unsigned char* pwd, unsigned char** encryptText, int &out_len)  
    {  
    	HCRYPTPROV hCryptProv = NULL;    
    	HCRYPTKEY hKey = 0;    
    	HCRYPTHASH hHash = 0;    
    	int dwLength = 0;    
    
    
    	OSVERSIONINFOW  VersionInformation = {sizeof(OSVERSIONINFOW)};
    
    	GetVersionExW(&VersionInformation);
    	LPCWSTR CSP_NAME = MS_ENH_RSA_AES_PROV_XP_W;
    	if ( VersionInformation.dwMajorVersion != 5 )
    		CSP_NAME = MS_ENH_RSA_AES_PROV_W;
    
    	if(!CryptAcquireContext(&hCryptProv,    
    		NULL,    
    		CSP_NAME,//CSP_NAME     
    		PROV_RSA_AES,    
    		CRYPT_VERIFYCONTEXT))    
    	{    
    		DWORD dwLastErr = GetLastError();    
    
    		if(NTE_BAD_KEYSET == dwLastErr)     
    		{    
    			return;    
    		}    
    		else{    
    			if(!CryptAcquireContext(&hCryptProv,    
    				NULL,    
    				CSP_NAME,    
    				PROV_RSA_AES,    
    				CRYPT_NEWKEYSET))    
    			{    
    				return;    
    			}    
    		}    
    	}    
    	if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))    
    	{    
    		return;    
    	}    
    
    	BYTE *pPwd = pwd;   
    
    	if(!CryptHashData(hHash, pPwd, 16, 0))    
    	{    
    		return;    
    	}    
    //CRYPT_EXPORTABLE
    	if(!CryptDeriveKey(hCryptProv, CALG_AES_128, hHash,0x800000 , &hKey))//得到最后用来加密的密钥
    	{    
    		return;    
    	}    
    
    	int len = text.length();    
    	BYTE *pData ;    
    	pData = (BYTE*)malloc(len*4);    
    	memcpy(pData,text.c_str(),len);  
    	DWORD dwLen = len;    
    
    	if(!CryptEncrypt(hKey, NULL, true, 0, pData, &dwLen, len*4))    
    	{    
    		return;    
    	}    
    
    	cout <<"
    --------------------------
    " << endl << "cryptoAPI encrypt"<<endl;  
    	for (int i=0;i<dwLen;i++)
    	{
    		_tprintf(_T("%02x"), pData[i]);
    		//Ciphertext[i] = pData[i];
    	}
    	;    
    	*encryptText = pData;  
    	out_len = dwLen;  
    	CryptDestroyHash(hHash);  
    	CryptDestroyKey(hKey);  
    	CryptReleaseContext(hCryptProv,0);  
    } 
    
    void cryptAPI_decrypt(unsigned char* text,int len,unsigned char* pwd)  
    {  
    	HCRYPTPROV hCryptProv = NULL;    
    	HCRYPTKEY hKey = 0;    
    	HCRYPTHASH hHash = 0;    
    	int dwLength = 0;    
    
    
    	OSVERSIONINFOW  VersionInformation = {sizeof(OSVERSIONINFOW)};
    
    	GetVersionExW(&VersionInformation);
    	LPCWSTR CSP_NAME = MS_ENH_RSA_AES_PROV_XP_W;
    	if ( VersionInformation.dwMajorVersion != 5 )
    		CSP_NAME = MS_ENH_RSA_AES_PROV_W;
    
    
    	if(!CryptAcquireContext(&hCryptProv,    
    		NULL,    
    		CSP_NAME,//CSP_NAME     
    		PROV_RSA_AES,    
    		CRYPT_VERIFYCONTEXT))    
    	{    
    		DWORD dwLastErr = GetLastError();    
    
    		if(NTE_BAD_KEYSET == dwLastErr)     
    		{    
    			return;    
    		}    
    		else{    
    			if(!CryptAcquireContext(&hCryptProv,    
    				NULL,    
    				CSP_NAME,    
    				PROV_RSA_AES,    
    				CRYPT_NEWKEYSET))    
    			{    
    				return;    
    			}    
    		}    
    	}    
    
    
    	if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))    
    	{    
    		return;    
    	}    
    
    	BYTE *pPwd = pwd;   
    
    	if(!CryptHashData(hHash, pPwd, 16, 0))    
    	{    
    		return;    
    	}    
    
    	if(!CryptDeriveKey(hCryptProv, CALG_AES_128, hHash, 0x800000, &hKey))    
    	{    
    		return;    
    	}    
    
    	BYTE *pData = text;    
    	DWORD dwLen = len;    
    
    	if(!CryptDecrypt(hKey, NULL, true, 0, pData, &dwLen))    
    	{    
    		return;    
    	}    
    
    	cout <<"
    --------------------------
    " << endl << "cryptoAPI decrypt"<<endl;  
    	char* plainText = (char*)malloc(dwLen + 1);  
    	memcpy(plainText,pData,dwLen);  
    	plainText[dwLen] = '';  
    	cout << plainText << endl;  
    	CryptDestroyHash(hHash);  
    	CryptDestroyKey(hKey);  
    	CryptReleaseContext(hCryptProv,0);  
    }  
    
    void main()
    {
    	string pdata="abcdefghijklmnop";
    	BYTE key[] = "1234567890132456";
    	unsigned char *getstr;
    	int dwread;
    	cryptoAPI_encrypt(pdata,key,&getstr,dwread);
    
    	cryptAPI_decrypt(getstr,dwread,key);
    	return ;
    } // end main


    实验8````````````````````````````` 

    DES加密解密

    #include "stdafx.h"
    #include <stdio.h>
    #include <windows.h>
    #include <Wincrypt.h>
    #pragma comment (lib, "crypt32.lib")
    
    void main()
    {
    	struct
    	{
    		BLOBHEADER hdr;
    		DWORD cbKeySize;
    		BYTE rgbKeyData[8];
    	} keyBlob;
    
    	keyBlob.hdr.bType = PLAINTEXTKEYBLOB;//The key is a session key.
    	keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
    	keyBlob.hdr.reserved = 0;
    	keyBlob.hdr.aiKeyAlg = CALG_DES;
    	keyBlob.cbKeySize = 8;
    	BYTE Key[8] = {0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
    	BYTE Ciphertext[8];
    
    	CopyMemory(keyBlob.rgbKeyData, Key, keyBlob.cbKeySize);
    
    	BYTE pData[256] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38};
    	DWORD dwDataLen = 8;
    
    	HCRYPTPROV hProv;
    	if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
    	{
    		HCRYPTKEY hKey;
    		if (CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), 0, 0, &hKey))
    		{
    			DWORD dwMode = CRYPT_MODE_CBC;
    			CryptSetKeyParam(hKey, KP_MODE, (BYTE*)(&dwMode), 0);
    			CryptEncrypt(hKey, 0, TRUE, 0, pData, &dwDataLen, _countof(pData));
    			for (int i = 0; i != 8 /*dwDataLen*/; ++i)
    				{
    					_tprintf(_T("%02x "), pData[i]);
    					Ciphertext[i] = pData[i];
    				}
    			_tprintf(_T("
    "));
    			CryptDestroyKey(hKey);
    		}
    		CryptReleaseContext(hProv, 0);
    	}
    
    	if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
    	{
    		HCRYPTKEY hKey2;
    		if (CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), 0, 0, &hKey2))
    		{
    			DWORD dwMode = CRYPT_MODE_CBC;
    			CryptSetKeyParam(hKey2, KP_MODE, (BYTE*)(&dwMode), 0);
    			CryptDecrypt(hKey2, 0, TRUE, 0, pData, &dwDataLen);
    			for (int i = 0; i != 8 /*dwDataLen*/; ++i)
    			{
    				_tprintf(_T("%02x "), pData[i]);
    				Ciphertext[i] = pData[i];
    			}
    			_tprintf(_T("
    "));
    			CryptDestroyKey(hKey2);
    		}
    		CryptReleaseContext(hProv, 0);
    	}
    	return ;
    } // end main


    实验7`````````````````````````````

    /*
    下面我们来看看如何哈希一个对话密钥,这个密钥可以用来对一个消息,文件进行加密。我们依旧从一个程序开始。
    */
    #include "stdafx.h"
    #include <stdio.h>
    #include <windows.h>
    #include <Wincrypt.h>
    #pragma comment (lib, "crypt32.lib")
    #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    
    
    void MyHandleError(LPTSTR psz)
    {
    	_ftprintf(stderr, TEXT("An error occurred in the program. 
    "));
    	_ftprintf(stderr, TEXT("%s
    "), psz);
    	_ftprintf(stderr, TEXT("Error number %x.
    "), GetLastError());
    	_ftprintf(stderr, TEXT("Program terminating. 
    "));
    	exit(1);
    } // End of MyHandleError.
    
    void main()
    {
    
    	//--------------------------------------------------------------------
    	// Copyright (c) Microsoft Corporation.  All rights reserved.
    	// Declare variables.
    
    	HCRYPTPROV hCryptProv;
    	HCRYPTHASH hHash;
    	HCRYPTKEY hKey;
    
    	//--------------------------------------------------------------------
    	// Begin processing.
    
    	printf("Process beginning. Creating a session key. 
    ");
    	BYTE pData[11]="1234567890";
    
    	if(CryptAcquireContext(                           // 首先依旧是获取一个缺省的CSP句柄
    		&hCryptProv, 
    		NULL, 
    		NULL, 
    		PROV_RSA_FULL, 
    		0)) 
    	{
    		printf("CryptAcquireContext complete. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Acquisition of context failed."));
    	}
    
    	if(CryptCreateHash(                            //     创建一个CALG_MD5算法的HASH对象,这个hash对象用的是MD5算法
    		hCryptProv,                                 //        指定一个CSP句柄
    		CALG_MD5,                                   //    指定算法
    		0,               
    		0, 
    		&hHash)) 
    	{
    		printf("An empty hash object has been created. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptBeginHash!
    "));
    	}
    
    	if(CryptGenKey(                //  创建密钥
    		hCryptProv,               //  传入一个CSP句柄
    		CALG_RC2,                 //  指明密钥身成所用算法
    		CRYPT_EXPORTABLE,        //  说明密钥是可以导出到CSP,用于这个应用程序外的
    		&hKey)) 
    	{
    		printf("A random session key has been created. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptGenKey!
    "));
    	}
    	if(CryptHashSessionKey(                             //对生成的密钥进行hash
    		hHash, 
    		hKey, 
    		0))
    	{
    		printf("The session key has been hashed. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptHashSessionKey!
    "));
    	}
    	DWORD dwRead;							
    	//在这里就可以添加代码,用生成的密钥进行加密
    
    	
    
    		if(hHash)
    		{
    			if(!(CryptDestroyHash(hHash)))
    				MyHandleError(TEXT("Error during CryptDestroyHash"));
    		}
    
    
    		if(hKey)
    		{
    			if(!(CryptDestroyKey(hKey)))
    				MyHandleError(TEXT("Error during CryptDestroyKey"));
    		}
    
    		// Release the CSP.
    
    		if(hCryptProv)
    		{
    			if(!(CryptReleaseContext(hCryptProv,0)))
    				MyHandleError(TEXT("Error during CryptReleaseContext"));
    		}
    
    		printf("Create random session key completed without error. 
    ");
    } // end main


    实验6`````````````````````````````

    /*
    下面逐渐进入主题了,现在来讲讲是如何对数据进行Encoding and Decoding的。依旧是从一段程序中开始。
    */
    #include "stdafx.h"
    #include <stdio.h>
    #include <windows.h>
    #include <Wincrypt.h>
    #pragma comment (lib, "crypt32.lib")
    #define MY_ENCODING_TYPE  (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
    
    void MyHandleError(LPTSTR psz)
    {
    	_ftprintf(stderr, TEXT("An error occurred in the program. 
    "));
    	_ftprintf(stderr, TEXT("%s
    "), psz);
    	_ftprintf(stderr, TEXT("Error number %x.
    "), GetLastError());
    	_ftprintf(stderr, TEXT("Program terminating. 
    "));
    	exit(1);
    } // End of MyHandleError.
    
    
    void main(void)
    {
    	HCRYPTMSG hMsg;                         //指向一个消息句柄
    		BYTE* pbContent;                    //一个BYTE指针指向消息
    		DWORD cbContent;                    //消息长度
    		DWORD cbEncodedBlob;                //ECODE的BLOB的大小
    		BYTE *pbEncodedBlob;                //一个BYTE指针指向ENCODE BLOB
    
    		DWORD cbData = sizeof(DWORD);        //数据大小
    		DWORD cbDecoded;                     //Decode内容大小
    		BYTE *pbDecoded;                     //指向Decode的指针
    
    	pbContent = (BYTE*)"Security is our only business";
    	cbContent = strlen((char *) pbContent)+1;
    
    	printf("The original message => %s
    ",pbContent);  
    
    	if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
    		MY_ENCODING_TYPE,      //指定Encode类型,在程序的开头已经预定义了,MY_ENCODING_TYPE 就是 PKCS_7_ASN_ENCODING | X509_ASN_ENCODING
    		0,                      //Flags
    		CMSG_DATA,              // 定义了数据的类型,这里指定为BYTE型的字符串
    		NULL,                   
    		NULL,                   
    		cbContent))             //  内容的大小
    								//这里的的函数的作用是计算指定消息Encode所需要的最大的长度,通过计算,为一个BLOB分配内存空间。
    	{
    		printf("The length of the data has been calculated. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Getting cbEncodedBlob length failed"));
    	}
    	//为encode blob分配内存空间
    
    		if(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob))
    		{
    			printf("Memory has been allocated for the signed message. 
    ");
    		}
    		else
    		{
    			MyHandleError(TEXT("Memory allocation failed"));
    		}
    
    		if(hMsg = CryptMsgOpenToEncode(  //CryptMsgOpenToEncode为Encode,开一个消息
    			MY_ENCODING_TYPE,           // Encode类型,文件开始有说明
    			0,                          // Flags
    			CMSG_DATA,                  // 指定Message的类型,CMSG_DATA说明类型没用到
    			NULL,                       // 现在没有到,为NULL
    			NULL,                       // 同上
    			NULL))                      // 不是流加密,这个参数为NULL
    		{
    			printf("The message to be encoded has been opened. 
    ");
    		}
    		else
    		{
    			MyHandleError(TEXT("OpenToEncode failed"));
    		}
    		if(CryptMsgUpdate(                 // CryptMsgUpdate将数据加到消息中,可以通过循环,将数据一段段的加得到消息中
    			hMsg,                           // 一个小心句柄
    			pbContent,                      //    指向数据的指针
    			cbContent,                      //   数据的大小
    			TRUE))                         //   TRUE表明这个是最后一段数据,在开个消息的时候,如果CMSG_DETACHED_FLAG有使用到,这设为FALSE,否则为TRUE。
    		{
    			printf("Content has been added to the encoded message. 
    ");
    		}
    		else
    		{
    			MyHandleError(TEXT("MsgUpdate failed"));
    		}
    
    		if(CryptMsgGetParam(              // CryptMsgGetParam是获取一个消息中的参数
    			hMsg,                         // 一个消息句柄
    			CMSG_BARE_CONTENT_PARAM,      //指定要获取的参数的类型
    			0,                        
    			pbEncodedBlob,              //     一个接受数据的内存地址
    			&cbEncodedBlob))            //     BLOB的大小,即是上面接受的数据的大小
    		{
    			printf("Message encoded successfully. 
    encoded");
    			printf("The message is %s.
    ",(LPSTR)pbEncodedBlob);
    		}
    		else
    		{
    			MyHandleError(TEXT("MsgGetParam failed"));
    		}
    										//释放消息句柄
    			if(hMsg)
    				CryptMsgClose(hMsg);
    
    	//////////////////////////////////////////////////////////////////////////////////////////////
    
    		if(hMsg = CryptMsgOpenToDecode(  //开个Decode的小心句柄,参数和上面的Encode一样
    			MY_ENCODING_TYPE,      
    			0,                                   
    			CMSG_DATA,             
    			NULL,                  
    			NULL,                 
    			NULL))                
    		{
    			printf("The message to decode is open. 
    ");
    		}
    		else
    		{
    			MyHandleError(TEXT("OpenToDecode failed"));
    		}
    											//下面的过程和Encode类似,调用的函数和上面相同,只不过是过程逆向
    
    			printf("
    The length of the encoded message is %d.
    
    ",
    			cbEncodedBlob);
    
    		if(CryptMsgUpdate(
    			hMsg,                 // Handle to the message
    			pbEncodedBlob,        // Pointer to the encoded BLOB
    			cbEncodedBlob,        // Size of the encoded BLOB
    			TRUE))                // Last call
    		{
    			printf("The encoded BLOB has been added to the message. 
    ");
    		}
    		else
    		{
    			MyHandleError(TEXT("Decode MsgUpdate failed"));
    		}
    		if(CryptMsgGetParam(     // CryptMsgGetParam的调用和上面有所不同,这里一共是调用两次,第一次的作用主要是得到消息的大小,第二次是得到消息所在的内存地址
    			hMsg,                 //消息句柄
    			CMSG_CONTENT_PARAM,    // Parameter type
    			0,                     
    			NULL,                  // Address for returned 
    			// information
    			&cbDecoded))           // Size of the returned
    			// information
    		{
    			printf("The decoded message size is %d. 
    ", cbDecoded);
    		}
    		else
    		{
    			MyHandleError(TEXT("Decode CMSG_CONTENT_PARAM failed"));
    		}
    		if(pbDecoded = (BYTE *) malloc(cbDecoded))
    		{
    			printf("Memory has been allocated for the decoded message.
    ");
    		}
    		else
    		{
    			MyHandleError(TEXT("Decoding memory allocation failed."));
    		}
    		if(CryptMsgGetParam(
    			hMsg,                  // Handle to the message
    			CMSG_CONTENT_PARAM,    // Parameter type
    			0,                     // Index
    			pbDecoded,             // Address for returned 
    			// information
    			&cbDecoded))           // Size of the returned 
    			// information
    		{
    			printf("The message is %s.
    ",(LPSTR)pbDecoded);
    		}
    		else
    		{
    			MyHandleError(TEXT("Decode CMSG_CONTENT_PARAM #2 failed"));
    		}
    		if(pbEncodedBlob)
    			free(pbEncodedBlob);
    		if(pbDecoded)
    			free(pbDecoded);
    		if(hMsg)
    			CryptMsgClose(hMsg);
    
    		printf("This program ran to completion without error. 
    ");
    
    } //  End of main


    实验5`````````````````````````````

    /*
    当我们已经生成了一个密钥,我们下面要做的是如何保存,导出,导入一个对话密钥。将一个密钥保存起来,导出,保存到硬盘上。这样,这个密钥就可以在其它应用程序上使用,而不会随着生成密钥程序的关闭而丢失了。
    	下面这段程序就是用来演示如何保存,导出一个对话密钥的。
    */
    #include "stdafx.h"
    #include <stdio.h>
    #include <windows.h>
    #include <Wincrypt.h>
    #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    
    void MyHandleError(LPTSTR psz)
    {
    	_ftprintf(stderr, TEXT("An error occurred in the program. 
    "));
    	_ftprintf(stderr, TEXT("%s
    "), psz);
    	_ftprintf(stderr, TEXT("Error number %x.
    "), GetLastError());
    	_ftprintf(stderr, TEXT("Program terminating. 
    "));
    	exit(1);
    } // End of MyHandleError.
    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(                         //    获取一个缺省容器的CSP句柄
    		&hProv, 
    		NULL, 
    		NULL, 
    		PROV_RSA_FULL, 
    		0)) 
    	{
    		printf("The CSP has been acquired. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptAcquireContext."));
    	}
    
    	if(CryptGetUserKey(         // CryptGetUserKey是获取一个密钥//句柄的函数,成功返回TRUE
    		hProv,             //指定容器的CSP模块句柄
    		AT_SIGNATURE,           //指定私钥的类型
    		&hSignKey))                  //原来接收获取的密钥句柄
    	{
    		_tprintf(TEXT("A signature key is available.
    "));
    	}
    	else
    	{
    		_tprintf(TEXT("No signature key is available.
    "));
    		if(GetLastError() == NTE_NO_KEY)      // NTE_NO_KEY意味着密钥不存在,下面就生成一个密钥
    		{
    
    			_tprintf(TEXT("The signature key does not exist.
    "));
    			_tprintf(TEXT("Create a signature key pair.
    ")); 
    			if(CryptGenKey(    // CryptGenKey生成一个密钥
    				hProv,    //指定CSP模块的句柄
    				AT_SIGNATURE,  //对于公钥密码系统,生成一个私钥和一个公钥,这个参数指定了这个密钥是公钥,于是生成了一个密码对。如果不是公钥系统,则指定了密码算法,具体看MSDN。
    				0,             //指定了生成密钥的类型,这个参数的说明挺多的,想获取更为详尽的资料请看MSDN。
    				&hSignKey)) 
    			{
    				_tprintf(TEXT("Created a signature key pair.
    "));
    			}
    			else
    			{
    				MyHandleError(TEXT("Error occurred creating a ")
    					TEXT("signature key.
    ")); 
    			}
    		}
    		else
    		{
    			MyHandleError(TEXT("An error other than NTE_NO_KEY ")
    				TEXT("getting a signature key.
    "));
    		}
    	} // End if.
    
    
    	//--------------------------------------------------------------------
    
    	if(CryptGetUserKey(                              //        获取一个AT_KEYEXCHANGE,类型的密钥句柄,保存在hXchgKey中
    		hProv, 
    		AT_KEYEXCHANGE, 
    		&hXchgKey)) 
    	{
    		printf("The key exchange key has been acquired. 
    ");
    	}
    	else
    	{
    		printf("Error during CryptGetUserKey exchange key.");
    	}
    	// Generate a session key.
    
    	if (CryptGenKey(                                  //生成一个CRYPT_EXPORTABLE(可导出的),CALG_RC4(指定算法)的密钥,保存在hKey
    		hProv,      
    		CALG_RC4,      
    		CRYPT_EXPORTABLE, 
    		&hKey))
    	{   
    		printf("Original session key is created. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("ERROR -- CryptGenKey."));
    	}
    	if(CryptExportKey(                                 //  CryptExportKey导出一个密钥
    		hKey,                                         // 将要导出的密钥的句柄
    		hXchgKey,									//用户最终使用到的密钥的句柄
    		SIMPLEBLOB,                               // 指定BLOB的类型,SIMPLEBLOB说明是 用来导出对话密钥的
    		0,                                            // 指定密钥的附加属性
    		NULL,                                         
    		&dwBlobLen))                                 // 当时这个函数在这里的主要
    													//目的是得到这个BLOB的长度
    	{
    		printf("Size of the BLOB for the session key determined. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error computing BLOB length."));
    	}
    
    	if(pbKeyBlob = (BYTE*)malloc(dwBlobLen)) 
    	{
    		printf("Memory has been allocated for the BLOB. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Out of memory. 
    "));
    	}
    	if(CryptExportKey(                            //这是这个函数才是真正的导出密钥
    		hKey, 
    		hXchgKey, 
    		SIMPLEBLOB, 
    		0, 
    		pbKeyBlob, 
    		&dwBlobLen))
    	{
    		printf("Contents have been written to the BLOB. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptExportKey."));
    	}
    	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. 
    ");
    
    }


    实验4`````````````````````````````

    /*
    讲如何复制一个对话密钥,照例是从一个程序讲起,完成以下任务。获取一个CSP句柄,
    创建一个对话密钥,复制密钥。改变密钥生成过程,随机填充一个缓冲区,销毁密钥句柄,释放CSP句柄
    */
    #include "stdafx.h"
    #include <stdio.h>
    #include <tchar.h>
    #include <string.h>
    #include <conio.h>
    #include <windows.h>
    #include <Wincrypt.h>
    #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    
    void MyHandleError(LPTSTR psz)
    {
    	_ftprintf(stderr, TEXT("An error occurred in the program. 
    "));
    	_ftprintf(stderr, TEXT("%s
    "), psz);
    	_ftprintf(stderr, TEXT("Error number %x.
    "), GetLastError());
    	_ftprintf(stderr, TEXT("Program terminating. 
    "));
    	exit(1);
    } // End of MyHandleError.
    
    void GetConsoleInput(char* strInput, 
    	int   intMaxChars)
    {
    	char ch;
    	char minChar = ' ';
    	minChar++;
    
    	ch = getch();
    	while (ch != '
    ')
    	{
    		if (ch == '' && strlen(strInput) > 0)
    		{
    			strInput[strlen(strInput)-1]   = '';
    			printf(" ");
    		}
    		else if (ch >= minChar && strlen(strInput) < intMaxChars)
    		{
    			strInput[strlen(strInput)+1] = '';
    			strInput[strlen(strInput)]   = ch;
    			putch('*');
    		}
    		ch = getch();
    	}
    	putch('
    ');
    }
    
    void main()
    {
    	//-------------------------------------------------------------------
    	// Declare and initialize variables.
    
    	HCRYPTPROV   hCryptProv;                        // CSP句柄
    		HCRYPTKEY    hOriginalKey;              // 源密钥句柄
    		HCRYPTKEY    hDuplicateKey;              // 复制后的密钥句柄
    		DWORD        dwMode;                            
    	BYTE          pbData[16];
    
    	printf("This program creates a session key and duplicates 
    ");
    	printf("that key. Next, parameters are added to the original 
    ");
    	printf("key. Finally, both keys are destroyed. 
    
    ");
    
    	if(CryptAcquireContext(                    //   获取CSP句柄,前面叙述过了,这里就不叙述了
    		&hCryptProv,
    		NULL,
    		NULL,
    		PROV_RSA_FULL,
    		0)) 
    	{    
    		printf("CryptAcquireContext succeeded. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptAcquireContext!
    "));
    	}
    	//-------------------------------------------------------------------
    	if (CryptGenKey(                     // 生成一个CALG_RC4算法生成的密钥,保存在hOriginalKey中
    		hCryptProv, 
    		CALG_RC4,                        // ALG_ID结构,指定生成这个密钥使用的算法
    		0, 
    		&hOriginalKey))
    	{
    		printf("Original session key is created. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("ERROR - CryptGenKey."));
    	}
    
    	if (CryptDuplicateKey(                          //  复制密钥
    		hOriginalKey,                               //  源密钥
    		NULL,                                       // 保留参数,必须为NULL
    		0,                                          // 保留参数,必须为0
    		&hDuplicateKey))                            //  副本密钥
    	{
    		printf("The session key has been duplicated. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("ERROR - CryptDuplicateKey"));
    	}
    											// 给源密钥设置附加参数
    		dwMode = CRYPT_MODE_ECB;            //CRYPT_MODE_ECB是一个没有反馈的块加密模式  
    		if(CryptSetKeyParam(
    			hOriginalKey, 
    			KP_MODE,						// KP_MODE指定密钥的某种属性被改变,
    											// 意味着改变的是加密模式
    			(BYTE*)&dwMode,              //     指向一个已经被初始化的缓冲区
    			0))                                          
    		{
    			printf("Key Parameters set. 
    ");
    		}
    		else
    		{
    			MyHandleError(TEXT("Error during CryptSetKeyParam."));
    		}
    		if(CryptGenRandom(              //                随机填充一块缓冲区
    			hCryptProv,                //                   CSP句柄
    			8,                       //  缓冲区大小
    			pbData))                 //      缓冲区地址
    		{
    			printf("Random sequence generated. 
    ");
    		}
    		else
    		{
    			MyHandleError(TEXT("Error during CryptGenRandom."));
    		}
    		if(CryptSetKeyParam(           //再次给密钥设置属性
    			hOriginalKey, 
    			KP_IV,               // KP_IV意味着,这个函数的第三个参数指向一个BYTE数组,数组大小为块大小/8。
    			pbData, 
    			0)) 
    		{
    			printf("Parameter set with random sequence as "
    				"initialization vector. 
    ");
    		}
    		else
    		{
    			MyHandleError(TEXT("Error during CryptSetKeyParam."));
    		}
    		//-------------------------------------------------------------------
    
    		if (hOriginalKey)                  //                  以下依次销毁,释放源密钥句柄,副本句柄,CSP句柄,
    			if (!CryptDestroyKey(hOriginalKey))
    				MyHandleError(TEXT("Failed CryptDestroyKey
    "));
    
    		if (hDuplicateKey)
    			if (!CryptDestroyKey(hDuplicateKey))
    				MyHandleError(TEXT("Failed CryptDestroyKey
    "));
    
    		if(hCryptProv)
    			if (!CryptReleaseContext(hCryptProv, 0))
    				MyHandleError(TEXT("Failed CryptReleaseContext
    "));
    
    		printf("
    The program ran to completion without error. 
    ");
    
    } // End of main.



    实验3`````````````````````````````

    /*任务一:调用CryptAcquireContext,获取一个缺省CSP和缺省密钥容器的句柄
    	任务二:用CryptCreateHash去创建一个空的哈希对象
    	任务三:用CryptHashData.哈希密码
    	任务四:调用CryptDeriveKey获取一个对话密钥
    	任务五:销毁密码和哈希后的数据
    	任务六:释放CSP
    */
    #include "stdafx.h"
    #include <stdio.h>
    #include <tchar.h>
    #include <string.h>
    #include <conio.h>
    #include <windows.h>
    #include <Wincrypt.h>
    
    void MyHandleError(LPTSTR psz)
    {
    	_ftprintf(stderr, TEXT("An error occurred in the program. 
    "));
    	_ftprintf(stderr, TEXT("%s
    "), psz);
    	_ftprintf(stderr, TEXT("Error number %x.
    "), GetLastError());
    	_ftprintf(stderr, TEXT("Program terminating. 
    "));
    	exit(1);
    } // End of MyHandleError.
    
    void GetConsoleInput(char* strInput, 
    	int   intMaxChars)
    {
    	char ch;
    	char minChar = ' ';
    	minChar++;
    
    	ch = getch();
    	while (ch != '
    ')
    	{
    		if (ch == '' && strlen(strInput) > 0)
    		{
    			strInput[strlen(strInput)-1]   = '';
    			printf(" ");
    		}
    		else if (ch >= minChar && strlen(strInput) < intMaxChars)
    		{
    			strInput[strlen(strInput)+1] = '';
    			strInput[strlen(strInput)]   = ch;
    			putch('*');
    		}
    		ch = getch();
    	}
    	putch('
    ');
    }
    void main()
    {
    
    	HCRYPTPROV hCryptProv;                       // 定义CSP句柄
    		HCRYPTKEY hKey;                          // 定义密钥句柄
    		HCRYPTHASH hHash;                        // 定义一个HASH对象的句柄
    		CHAR szPassword[512] = "";               // 定义512大小的字符数组,用来保存密码
    		DWORD dwLength;                          // 保存密码长度
    		fprintf(stderr,"Enter a password to be used to create a key:");
    
    	GetConsoleInput(szPassword, 512);             //  获取密码,这个是自己写的函数,目的是在屏幕上显示的是*。
    		printf("The password has been stored.
    ");
    	dwLength = strlen(szPassword);
    
    
    	if(CryptAcquireContext(                    //以下是获取一个缺省的PROV_RSA_FULL  CSP 句柄
    		&hCryptProv, 
    		NULL, 
    		NULL, 
    		PROV_RSA_FULL, 
    		0)) 
    	{
    		printf("A context has been acquired. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptAcquireContext!"));
    	}
    	//--------------------------------------------------------------------
    	if(CryptCreateHash(                             //  调用CryptCreateHash创建一个HASH对象
    		hCryptProv,                                 //   一个CSP句柄
    		CALG_MD5,                                   //  确定哈希算法   8003h
    		0,    //对于非密钥算法,这个参数一定是0,如果是密钥算法,那么这个参数就是密钥
    		0,     //                      保留参数,为0
    		&hHash))                                       //  一个哈希对象的指针
    	{
    		printf("An empty hash object has been created. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptCreateHash!"));
    	}
    	//--------------------------------------------------------------------
    	if(CryptHashData(                        //   调用CryptHashData哈希密码
    		hHash,                               //   哈希对象
    		(BYTE *)szPassword,                  // 指向缓冲区的地址
    		dwLength,                            //           密码长度
    		0)) 
    	{
    		printf("The password has been hashed. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptHashData!"));
    	}
    	//--------------------------------------------------------------------
    	if(CryptDeriveKey(                //调用CryptDeriveKey获取对话密码
    		hCryptProv,                   // CSP句柄
    		CALG_RC2,                     // 6602h 一个ALG_ID结构,用来指定对称密钥生成的算法
    		hHash,                        // 哈希对象
    		CRYPT_EXPORTABLE,             //指定生成密钥的类型,CRYPT_EXPORTABLE意味着这个程序生成的密钥可以被其它程序调用,而不是仅仅限于这个程序当中。但是它不能用于非对称密码中。
    		&hKey)) 
    	{
    		printf("The key has been derived. 
    ");
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptDeriveKey!"));
    	}
    	if(hHash)                                         //  销毁哈希对象
    	{
    		if(!(CryptDestroyHash(hHash)))
    			MyHandleError(TEXT("Error during CryptDestroyHash"));
    	}
    
    	if(hKey)                                         //   销毁密钥句柄
    	{
    		if(!(CryptDestroyKey(hKey)))
    			MyHandleError(TEXT("Error during CryptDestroyKey"));
    	}
    
    	if(hCryptProv)                                     //  销毁CSP句柄
    	{
    		if(!(CryptReleaseContext(hCryptProv, 0)))
    			MyHandleError(TEXT("Error during CryptReleaseContext"));
    	}
    	printf("The program to derive a key completed without error. 
    ");
    } // end main



    实验2`````````````````````````````

    /*这个程序演示了以下内容和几个函数。
    	一.  用CryptAcquireContext获取一个缺省容器的缺省CSP的句柄。如果缺省容器不存在,用CryptAcquireContext创建一个。
    	二.  用CryptGetProvParam获取CSP和容器的信息。
    	三.  用CryptContextAddRef增加CSP的引用计数器的数值。
    	四.  用CryptAcquireContext创建一个指定的容器
    	五.  用CryptAcquireContext删除一个容器
    	六.  用一个新创建的容器获取一个CSP的句柄。
    */
    #include <stdio.h>
    #include "stdafx.h"
    #include <tchar.h>
    #include <windows.h>
    #include <Wincrypt.h>
    
    	void MyHandleError(LPTSTR psz)
    {
    	_ftprintf(stderr, TEXT("An error occurred in the program. 
    "));
    	_ftprintf(stderr, TEXT("%s
    "), psz);
    	_ftprintf(stderr, TEXT("Error number %x.
    "), GetLastError());
    	_ftprintf(stderr, TEXT("Program terminating. 
    "));
    	exit(1);
    } // End of MyHandleError.
    
    void main(void)
    {
    
    	HCRYPTPROV hCryptProv;                            //定义CSP句柄
    
    	if(CryptAcquireContext(
    		&hCryptProv, 
    		NULL,                                           //缺省容器
    		NULL,                                           //缺省CSP
    		PROV_RSA_FULL, 
    		0)) 
    	{
    		_tprintf(TEXT("CryptAcquireContext succeeded.
    "));
    	}
    	else
    	{
    		if (GetLastError() == NTE_BAD_KEYSET)               //同样,如果当不存在这样的容器的时候,创建一个
    		{
    			if(CryptAcquireContext(
    				&hCryptProv, 
    				NULL, 
    				NULL, 
    				PROV_RSA_FULL, 
    				CRYPT_NEWKEYSET))                     
    			{
    				_tprintf(TEXT("CryptAcquireContext succeeded.
    "));
    			}
    			else
    			{
    				MyHandleError(TEXT("Could not create the default ")
    					TEXT("key container.
    "));
    			}
    		}
    		else
    		{
    			MyHandleError(TEXT("A general error running ")
    				TEXT("CryptAcquireContext."));
    		}
    	}
    
    	CHAR pszName[1000];
    	DWORD cbName;
    
    	cbName = 1000;
    	if(CryptGetProvParam(
    		hCryptProv,                         //CSP模块句柄
    		PP_NAME,                            //指定获取哪些信息,这里是指定获取CSP名字的信息
    		(BYTE*)pszName,                     //缓冲区接受信息返回值
    		&cbName, 
    		0))
    	{
    		_tprintf(TEXT("CryptGetProvParam succeeded.
    "));
    		printf("Provider name: %s
    ", pszName);
    	}
    	else
    	{
    		MyHandleError(TEXT("Error reading CSP name.
    "));
    	}
    
    	//---------------------------------------------------------------
    	// Read the name of the key container.
    	cbName = 1000;
    	if(CryptGetProvParam(
    		hCryptProv, 
    		PP_CONTAINER,                                       //获取容器名字
    		(BYTE*)pszName, 
    		&cbName, 
    		0))
    	{
    		_tprintf(TEXT("CryptGetProvParam succeeded.
    "));
    		printf("Key Container name: %s
    ", pszName);
    	}
    	else
    	{
    		MyHandleError(TEXT("Error reading key container name.
    "));
    	}
    
    	//增加CSP的引用计数器的数值。
    	if(CryptContextAddRef( // CryptContextAddRef是向一个CSP的引用计数器增加一个值的函数
    		hCryptProv, 
    		NULL,              //保留值,必须为NULL
    		0))               //保留值,必须为0
    	{
    		_tprintf(TEXT("CryptcontextAddRef succeeded.
    "));
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptContextAddRef!
    "));
    	}
    
    	//---------------------------------------------------------------
    	//  The reference count on hCryptProv is now greater than one. 
    	//  The first call to CryptReleaseContext will not release the 
    	//  provider handle. 
    
    	//---------------------------------------------------------------
    	//  Release the context once.
    	if (CryptReleaseContext(hCryptProv, 0))  // CryptReleaseContext是用来释放CSP句柄的,当这个函数调用一次的时候,CSP里面的引用计数就减少一,当引用计数减少的0的时候。CSP将不能再被这个程序中的任何函数调用了。
    	{
    		_tprintf(TEXT("The first call to CryptReleaseContext ")
    			TEXT("succeeded.
    "));
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during ")
    			TEXT("CryptReleaseContext #1!
    "));
    	}
    
    	if (CryptReleaseContext(hCryptProv, 0))                //再次释放CSP模块
    	{
    		_tprintf(TEXT("The second call to CryptReleaseContext ")
    			TEXT("succeeded.
    "));
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during ")
    			TEXT("CryptReleaseContext #2!
    "));
    	}
    
    	//下面是从PROV_RSA_FULL的CSP模块中创建一个自己的容器
    		LPCTSTR pszContainerName = TEXT("My Sample Key Container");
    
    	hCryptProv = NULL;
    	if(CryptAcquireContext(
    		&hCryptProv, 
    		pszContainerName,
    		NULL, 
    		PROV_RSA_FULL, 
    		CRYPT_NEWKEYSET)) 
    	{
    		_tprintf(TEXT("CryptAcquireContext succeeded. 
    "));
    		_tprintf(TEXT("New key set created. 
    ")); 
    
    		//-----------------------------------------------------------
    		// Release the provider handle and the key container.
    		if(hCryptProv)
    		{
    			if(CryptReleaseContext(hCryptProv, 0)) 
    			{
    				hCryptProv = NULL;
    				_tprintf(TEXT("CryptReleaseContext succeeded. 
    "));
    			}
    			else
    			{
    				MyHandleError(TEXT("Error during ")
    					TEXT("CryptReleaseContext!
    "));
    			}
    		}
    	}
    	else
    	{
    		if(GetLastError() == NTE_EXISTS)
    		{
    			_tprintf(TEXT("The named key container could not be ")
    				TEXT("created because it already exists.
    "));
    
    		}
    		else
    		{
    			MyHandleError(TEXT("Error during CryptAcquireContext ")
    				TEXT("for a new key container."));
    		}
    	}
    
    
    	if(CryptAcquireContext(
    		&hCryptProv, 
    		pszContainerName, 
    		NULL, 
    		PROV_RSA_FULL,
    		0)) 
    	{
    		_tprintf(TEXT("Acquired the key set just created. 
    "));
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptAcquireContext!
    "));
    	}
    
    	//---------------------------------------------------------------
    	// Perform cryptographic operations.
    
    	//---------------------------------------------------------------
    	if(CryptReleaseContext(
    		hCryptProv, 
    		0)) 
    	{
    		_tprintf(TEXT("CryptReleaseContext succeeded. 
    "));
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptReleaseContext!
    "));
    	}
    
    
    	if(CryptAcquireContext(
    		&hCryptProv, 
    		pszContainerName, 
    		NULL, 
    		PROV_RSA_FULL,
    	CRYPT_DELETEKEYSET)) //CRYPT_DELETEKEYSET意味着CryptAcquireContex删除一个指定的容器
    	{
    		_tprintf(TEXT("Deleted the key container just created. 
    "));
    	}
    	else
    	{
    		MyHandleError(TEXT("Error during CryptAcquireContext!
    "));
    	}
    }

    实验1`````````````````````````````

    #include "stdafx.h"
    #include <stdio.h>
    #include <tchar.h>
    #include <windows.h>
    #include <Wincrypt.h>
    
    /*
    任务一:获取一个指定的密钥容器,如果这个容器不存在,创建一个。
    任务二:如果容器中不存在一个签名密钥对,创建一个
    任务三:如果容器中不存在一个交换密钥对,创建一个
    */
    void MyHandleError(LPTSTR psz)
    {
    	_ftprintf(stderr, TEXT("An error occurred in the program. 
    "));
    	_ftprintf(stderr, TEXT("%s
    "), psz);
    	_ftprintf(stderr, TEXT("Error number %x.
    "), GetLastError());
    	_ftprintf(stderr, TEXT("Program terminating. 
    "));
    	exit(1);
    } // End of MyHandleError.
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HCRYPTPROV hCryptProv;   //定义一个CSP模块的句柄。“CSP模块,请查看《加密解密二》222页,那里有简单的说明,这里就不说了。     
    
    	LPCTSTR pszContainerName = TEXT("My Sample Key Container");//用一个TEXT宏定义一个容器的名字,
    
    
    	if(CryptAcquireContext(        //这个函数是获取有某个容器的CSP模块的指针,成功返回TRUE。
    		&hCryptProv,            //指向一个CSP模块句柄指针,里面用指定的容器
    		pszContainerName,       //指定容器的名称
    		NULL,                //这个参数这里用的是缺省值,指得是缺省得CSP模块,你也可以传入一个LPCTSTR类型的字符串,指定CSP模块
    		PROV_RSA_FULL,      //确定密钥的类型
    		0))                    //常设为0,还有些其他的类型,请看MSDN
    	{
    		_tprintf(
    			TEXT("A crypto context with the %s key container ")
    			TEXT("has been acquired.
    "), 
    			pszContainerName);
    	}
    	else
    	{ 
    		//不成功的处理段
    		if(GetLastError() == NTE_BAD_KEYSET)// NTE_BAD_KEYSET意味着密钥容器不存在,
    											//下面就去创建一个
    											//新的密钥容器
    		{
    			if(CryptAcquireContext(
    				&hCryptProv, 
    				pszContainerName, 
    				NULL, 
    				PROV_RSA_FULL, 
    				CRYPT_NEWKEYSET))           // CRYPT_NEWKEYSET意味着当指定容器不存在的时候,去创建一个容器。
    			{
    				_tprintf(TEXT("A new key container has been ")
    					TEXT("created.
    "));
    			}
    			else
    			{
    				MyHandleError(TEXT("Could not create a new key ")
    					TEXT("container.
    "));
    			}
    		}
    		else
    		{
    			MyHandleError(TEXT("CryptAcquireContext failed.
    "));
    		}
    	}
    
    
    	HCRYPTKEY hKey;            //创建一个密钥句柄
    
    	if(CryptGetUserKey(         // CryptGetUserKey是获取一个密钥//句柄的函数,成功返回TRUE
    		hCryptProv,             //指定容器的CSP模块句柄
    		AT_SIGNATURE,           //指定私钥的类型
    		&hKey))                  //原来接收获取的密钥句柄
    	{
    		_tprintf(TEXT("A signature key is available.
    "));
    	}
    	else
    	{
    		_tprintf(TEXT("No signature key is available.
    "));
    		if(GetLastError() == NTE_NO_KEY)      // NTE_NO_KEY意味着密钥不存在,下面就生成一个密钥
    		{
    
    			_tprintf(TEXT("The signature key does not exist.
    "));
    			_tprintf(TEXT("Create a signature key pair.
    ")); 
    			if(CryptGenKey(    // CryptGenKey生成一个密钥
    				hCryptProv,    //指定CSP模块的句柄
    				AT_SIGNATURE,  //对于公钥密码系统,生成一个私钥和一个公钥,这个参数指定了这个密钥是公钥,于是生成了一个密码对。如果不是公钥系统,则指定了密码算法,具体看MSDN。
    				0,             //指定了生成密钥的类型,这个参数的说明挺多的,想获取更为详尽的资料请看MSDN。
    				&hKey)) 
    			{
    				_tprintf(TEXT("Created a signature key pair.
    "));
    			}
    			else
    			{
    				MyHandleError(TEXT("Error occurred creating a ")
    					TEXT("signature key.
    ")); 
    			}
    		}
    		else
    		{
    			MyHandleError(TEXT("An error other than NTE_NO_KEY ")
    				TEXT("getting a signature key.
    "));
    		}
    	} // End if.
    
    	_tprintf(TEXT("A signature key pair existed, or one was ")
    		TEXT("created.
    
    "));
    
    	if(hKey)                              //将密钥句柄销毁
    	{
    		if(!(CryptDestroyKey(hKey)))
    		{
    			MyHandleError(TEXT("Error during CryptDestroyKey."));
    		}
    
    		hKey = NULL;
    	} 
    
    	//下面这部分和上面是类似的,只不过密钥类型不相同而已。
    		if(CryptGetUserKey(
    			hCryptProv,
    			AT_KEYEXCHANGE,
    			&hKey)) 
    		{
    			_tprintf(TEXT("An exchange key exists.
    "));
    		}
    		else
    		{
    			_tprintf(TEXT("No exchange key is available.
    "));
    
    			// 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.
    "));
    				_tprintf(TEXT("Attempting to create an exchange key ")
    					TEXT("pair.
    "));
    				if(CryptGenKey(
    					hCryptProv,
    					AT_KEYEXCHANGE,
    					0,
    					&hKey)) 
    				{
    					_tprintf(TEXT("Exchange key pair created.
    "));
    				}
    				else
    				{
    					MyHandleError(TEXT("Error occurred attempting to ")
    						TEXT("create an exchange key.
    "));
    				}
    			}
    			else
    			{
    				MyHandleError(TEXT("An error other than NTE_NO_KEY ")
    					TEXT("occurred.
    "));
    			}
    		}
    
    		// 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.
    "), pszContainerName);  
    
    	return 0;
    }









    转载至:  http://bbs.pediy.com/showthread.php?t=31357&highlight=Crypto+API



  • 相关阅读:
    Python数据分析与机器学习-Matplot_2
    Python数据分析与机器学习-Matplot_1
    1008. 数组元素循环右移问题 (20)
    Latex小技巧
    执行PowerShell脚本的时候出现"在此系 统上禁止运行脚本"错误
    Linux使用MentoHust联网线上校园网, 回到普通有线网络却连不上?
    Re:uxul
    Linux下nautilus的右键快捷菜单项设置
    从入门到入狱——搭讪技巧
    Latex命令
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982359.html
Copyright © 2011-2022 走看看