vc++网络安全编程范例(17)-open ssl 实现文件加密与解密

OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。 作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。
对称加密算法
OpenSSL一共提供了8种对称加密算法,其中7种是分组加密算法,仅有的一种流加密算法是RC4。这7种分组加密算法分别是AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都支持电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种常用的分组密码加密模式。其中,AES使用的加密反馈模式(CFB)和输出反馈模式(OFB)分组长度是128位,其它算法使用的则是64位。事实上,DES算法里面不仅仅是常用的DES算法,还支持三个密钥和两个密钥3DES算法。
非对称加密算法
OpenSSL一共实现了4种非对称加密算法,包括DH算法、RSA算法、DSA算法和椭圆曲线算法(EC)。DH算法一般用户密钥交换。RSA算法既可以用于密钥交换,也可以用于数字签名,当然,如果你能够忍受其缓慢的速度,那么也可以用于数据加密。DSA算法则一般只用于数字签名。
信息摘要算法
OpenSSL实现了5种信息摘要算法,分别是MD2、MD5、MDC2、SHA(SHA1)和RIPEMD。SHA算法事实上包括了SHA和SHA1两种信息摘要算法,此外,OpenSSL还实现了DSS标准中规定的两种信息摘要算法DSS和DSS1。

我们来用VC++实现文件加密,请见代码实现与注释讲解

#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define KEYLENGTH  0x00800000
void HandleError(char *s);
HCRYPTPROV GetCryptProv();

#define ENCRYPT_ALGORITHM CALG_RC4 
#define ENCRYPT_BLOCK_SIZE 8 


BOOL EncryptFile(
     PCHAR szSource, 
     PCHAR szDestination, 
     PCHAR szPassword); 

HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword);
HCRYPTKEY GenKeyByRandom(HCRYPTPROV hCryptProv,FILE* hDestination);
 
//-------------------------------------------------------------------
// Begin main.

void main(void) 
{ 
    PCHAR szSource; 
    PCHAR szDestination; 
    CHAR szPassword[100] = ""; 
    char  response;
 
	if(!(szSource=(char *)malloc(100)))
		HandleError("Memory allocation failed.");
	if(!(szDestination=(char *)malloc(100)))
		HandleError("Memory allocation failed.");

	printf("加密一个文件. \n\n");
	printf("请输入需要被加密文件的名称: ");
	fgets(szSource, 100, stdin);
	if(szSource[strlen(szSource)-1] == '\n')
		 szSource[strlen(szSource)-1] = '\0';
	printf("请输入需要输出文件文件的名称: ");
	fgets(szDestination, 100, stdin);
	if(szDestination[strlen(szDestination)-1] == '\n')
		 szDestination[strlen(szDestination)-1] = '\0';
	printf("要使用密码对这个文件加密吗? ( y/n ) ");
	response = getchar();
	if(response == 'y')
	{
		printf("请输入密码:");
		getchar();
		gets(szPassword);
	}
	else
	{
		printf("密钥将生成但没有使用密码. \n");
	}

	//-------------------------------------------------------------------
	// 调用函数 EncryptFile 进行实际的加密操作.
 
	if(EncryptFile(szSource, szDestination, szPassword))
	{
		   printf("对文件 %s 的加密已经成功! \n", 
			   szSource);
		   printf("加密后的数据存储在文件 %s 中.\n",szDestination);
	}
	else
	{
		  HandleError("解密文件出错!"); 
	}
	//-------------------------------------------------------------------
	// 释放内存.
	if(szSource)
		 free(szSource);
	if(szDestination)
		 free(szDestination);

} // end main
 
//-------------------------------------------------------------------
// 功能:加密原文szSource文件,加密后的数据存储在szDestination文件中
// 参数:
//  szSource:原文文件名
//  szDestination:加密后数据存储文件
//  szPassword:用户输入的密码
static BOOL EncryptFile(
        PCHAR szSource, 
        PCHAR szDestination, 
        PCHAR szPassword)
{ 
	//-------------------------------------------------------------------
	// 变量申明与初始化.

	FILE *hSource; 
	FILE *hDestination; 

	HCRYPTPROV hCryptProv; 
	HCRYPTKEY hKey; 


	PBYTE pbBuffer; 
	DWORD dwBlockLen; 
	DWORD dwBufferLen; 
	DWORD dwCount; 
 
	//-------------------------------------------------------------------
	// 打开原文文件. 
	if(hSource = fopen(szSource,"rb"))
	{
	   printf("原文文件 %s 已经打开. \n", szSource);
	}
	else
	{ 
	   HandleError("打开原文文件出错!");
	} 

	//-------------------------------------------------------------------
	// 打开目标文件. 
	if(hDestination = fopen(szDestination,"wb"))
	{
		 printf("目标文件 %s 已经打开. \n", szDestination);
	}
	else
	{
		HandleError("打开目标文件出错!"); 
	}
	//获取加密服务者句柄
	hCryptProv = GetCryptProv();

	//-------------------------------------------------------------------
	// 创建会话密钥.
	if(!szPassword || strcmp(szPassword,"")==0 ) 
	{ 
     
		 //--------------------------------------------------------------
		 // 当输入密码为空时,则创建随机的加密密钥,并导出创建的密钥保存到文件中. 

		hKey = GenKeyByRandom( hCryptProv, hDestination);

		 
	} 
	else 
	{ 
		 //--------------------------------------------------------------
		 // 当输入密码不为空时,则通过输入密码创建加密密钥

		hKey=GenKeyByPassword( hCryptProv, szPassword);
		
	} 
 
	//--------------------------------------------------------------------
	// 因为加密算法按ENCRYPT_BLOCK_SIZE 大小块加密,所以被加密的
	// 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的
	// 数据长度。

	dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; 

	//--------------------------------------------------------------------
	// 确定加密后密文数据块大小. 若是分组密码模式,则必须有容纳额外块的空间	

	if(ENCRYPT_BLOCK_SIZE > 1) 
		dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; 
	else 
		dwBufferLen = dwBlockLen; 
    
	//-------------------------------------------------------------------
	// 分配内存空间. 
	if(pbBuffer = (BYTE *)malloc(dwBufferLen))
	{
		printf("已经为缓冲区分配了内存. \n");
	}
	else
	{ 
		HandleError("所需内存不够. \n"); 
	}

	//-------------------------------------------------------------------
	// 循环加密 原文件
	do 
	{ 

		//-------------------------------------------------------------------
		// 每次从原文件中读取dwBlockLen字节数据. 
		dwCount = fread(pbBuffer, 1, dwBlockLen, hSource); 
		if(ferror(hSource))
		{ 
			HandleError("读取明文文件出错!\n");
		}
 
		//-------------------------------------------------------------------
		// 加密数据. 
		if(!CryptEncrypt(
			hKey,			//密钥
			0,				//如果数据同时进行散列和加密,这里传入一个散列对象
			feof(hSource),	//如果是最后一个被加密的块,输入TRUE.如果不是输入FALSE.
							//这里通过判断是否到文件尾来决定是否为最后一块。
			0,				//保留
			pbBuffer,		//输入被加密数据,输出加密后的数据
			&dwCount,		//输入被加密数据实际长度,输出加密后数据长度
			dwBufferLen))	//pbBuffer的大小。
		{ 
		   HandleError("Error during CryptEncrypt. \n"); 
		} 

		//-------------------------------------------------------------------
		// 把加密后数据写到密文文件中 

		fwrite(pbBuffer, 1, dwCount, hDestination); 
		if(ferror(hDestination))
		{ 
			HandleError("写入密文时出错.");
		}

	} 	while(!feof(hSource)); 

	//-------------------------------------------------------------------
	// 关闭文件

	if(hSource)
	{
		if(fclose(hSource))
			HandleError("关闭原文文件出错!");
	}
	if(hDestination)
	{
		if(fclose(hDestination))
			HandleError("关闭目标文件出错!");
	}

	//-------------------------------------------------------------------
	// 释放内存空间. 

	if(pbBuffer) 
		 free(pbBuffer); 
 
	//-------------------------------------------------------------------
	// 销毁会话密钥

	if(hKey)
	{
		if(!(CryptDestroyKey(hKey)))
			HandleError("Error during CryptDestroyKey");
	}

	//-------------------------------------------------------------------
	// 释放CSP句柄

	if(hCryptProv)
	{
		if(!(CryptReleaseContext(hCryptProv, 0)))
			HandleError("Error during CryptReleaseContext");
	}
	return(TRUE); 
} // end Encryptfile


//获取加密提供者句柄
HCRYPTPROV GetCryptProv()
{
	HCRYPTPROV hCryptProv;                      // 加密服务提供者句柄
	
	//获取加密提供者句柄
	if(CryptAcquireContext(
				&hCryptProv,         // 加密服务提供者句柄
				NULL,                // 密钥容器名,这里使用登陆用户名
				MS_ENHANCED_PROV,         // 加密服务提供者     
				PROV_RSA_FULL,       // 加密服务提供者类型,可以提供加密和签名等功能
				0))                  // 标志
	{
		printf("加密服务提供者句柄获取成功!\n");
	}
	else
	{
		
  
		//重新建立一个新的密钥集
	    if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
		{
		   HandleError("重新建立一个新的密钥集出错!");
		}
 
	}
	return hCryptProv;
}


//  HandleError:错误处理函数,打印错误信息,并退出程序
void HandleError(char *s)
{
    printf("程序执行发生错误!\n");
    printf("%s\n",s);
    printf("错误代码为: %x.\n",GetLastError());
    printf("程序终止执行!\n");
    exit(1);
}


// GenKeyByRandom:通过随机数创建会话密钥
// 参数:hCryptProv CSP句柄
//       hDestination 目标文件,导出的会话密钥保存在此文件中
HCRYPTKEY GenKeyByRandom(HCRYPTPROV hCryptProv,FILE* hDestination)
{
	HCRYPTKEY hKey; 
	HCRYPTKEY hXchgKey; 

	PBYTE pbKeyBlob; 
	DWORD dwKeyBlobLen; 

	if(CryptGenKey(
		  hCryptProv, 
		  ENCRYPT_ALGORITHM, 
		  KEYLENGTH | CRYPT_EXPORTABLE, 
		  &hKey))
	  {
		  printf("一个会话密钥已经被创建. \n");
	  } 
	  else
	  {
		  HandleError("Error during CryptGenKey. \n"); 
	  }
	 //--------------------------------------------------------------
	   // 创建交换密钥
	   if(CryptGenKey(
		   hCryptProv,
		   AT_KEYEXCHANGE,
		   0,
		   &hXchgKey)) 
	   {
		   printf("交换密钥对已经创建.\n");
	   }
	   else
	   {
		  HandleError("在试图创建交换密钥时出错.\n");
	   }

	 //--------------------------------------------------------------
	 // 确定密钥数据块长度,并分配空间. 

	 if(CryptExportKey(
		   hKey, 
		   hXchgKey, 
		   SIMPLEBLOB, 
		   0, 
		   NULL, 
		   &dwKeyBlobLen))
	 {
		   printf("此密钥块的长度是 %d 字节. \n",dwKeyBlobLen);
	   }
	   else
	   {  
			HandleError("计算密钥数据块长度出错! \n");
	   }
	   if(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen))
	   { 
		  printf("已经问此密钥块分配了内存. \n");
	   }
	   else
	   { 
		  HandleError("所需内存不够. \n"); 
	   }
	 //--------------------------------------------------------------
	 // 导出会话密钥到简单密钥数据块中. 
 
	 if(CryptExportKey(
		  hKey, 
		  hXchgKey, 
		  SIMPLEBLOB, 
		  0, 
		  pbKeyBlob, 
		  &dwKeyBlobLen))
	   {
		   printf("此会话密钥已经被导出. \n");
	   } 
	   else
	   {
		   HandleError("Error during CryptExportKey!\n");
	   } 
	 //--------------------------------------------------------------
	 //释放交换密钥句柄. 

	 if(hXchgKey)
	 {
		  if(!(CryptDestroyKey(hXchgKey)))
			   HandleError("Error during CryptDestroyKey"); 

		  hXchgKey = 0;
	 }

	 //--------------------------------------------------------------
	 // 写密钥块长度到目标文件. 

	 fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination); 
	 if(ferror(hDestination))
	 { 
		 HandleError("写密钥块长度出错.");
	 }
	 else
	 {
		 printf("密钥块长度已经被写入. \n");
	 }
	 //--------------------------------------------------------------
	 //写密钥块数据到目标文件. 
 
	 fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination); 
	 if(ferror(hDestination))
	 { 
		HandleError("写密钥数据出错");
	 }
	 else
	 {
		printf("此密钥块数据已经被写入目标文件. \n");
	 }
	 // 释放内存空间.
	 free(pbKeyBlob);
	 //返回创建的会话密钥
	 return hKey;
}

// GenKeyByRandom:通过输入密码创建会话密钥
// 参数:hCryptProv CSP句柄
//       szPassword 输入密码
HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword)
{
	HCRYPTKEY hKey; 
	HCRYPTHASH hHash;
	//-------------------------------------------------------------------
	// 创建哈希句柄. 

	if(CryptCreateHash(
		   hCryptProv, 
		   CALG_MD5, 
		   0, 
		   0, 
		   &hHash))
		{
			printf("一个哈希句柄已经被创建. \n");
		}
		else
		{ 
			 HandleError("Error during CryptCreateHash!\n");
		}  
	//-------------------------------------------------------------------
	// 计算输入密码的哈希值. 

	if(CryptHashData(
		   hHash, 
		   (BYTE *)szPassword, 
		   strlen(szPassword), 
		   0))
	 {
		printf("密码已经被添加到了哈希表中. \n");
	 }
	 else
	 {
		HandleError("Error during CryptHashData. \n"); 
	 }
	//-------------------------------------------------------------------
	// 通过哈希值创建会话密钥. 

	if(CryptDeriveKey(
		   hCryptProv, 
		   ENCRYPT_ALGORITHM, 
		   hHash, 
		   KEYLENGTH, 
		   &hKey))
	 {
	   printf("通过密码的哈希值获得了加密密钥. \n"); 
	 }
	 else
	 {
	   HandleError("Error during CryptDeriveKey!\n"); 
	 }
	//-------------------------------------------------------------------
	// 销毁哈希句柄. 

	if(hHash) 
	{
		if(!(CryptDestroyHash(hHash)))
		   HandleError("Error during CryptDestroyHash"); 
		hHash = 0;
	}

	//返回创建的会话密钥
	return hKey;
}


 

我们来用VC++实现文件解密,请见代码实现与注释讲解

 

#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define KEYLENGTH  0x00800000
void HandleError(char *s);
HCRYPTPROV GetCryptProv();

#define ENCRYPT_ALGORITHM CALG_RC4 
#define ENCRYPT_BLOCK_SIZE 8 
 
BOOL DecryptFile(
     PCHAR szSource, 
     PCHAR szDestination, 
     CHAR *szPassword); 

HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword);
HCRYPTKEY GenKeyFromFile(HCRYPTPROV hCryptProv,FILE* hSource);

void main(void) 
{ 
	//--------------------------------------------------------------------
	// 变量申明与初始化.

	PCHAR szSource; 
	PCHAR szDestination; 
	CHAR szPassword[100] = ""; 
	char  response;

	if(!(szSource=(char *)malloc(100)))
		HandleError("Memory allocation failed.");
	if(!(szDestination=(char *)malloc(100)))
		HandleError("Memory allocation failed.");

	printf("解密一个文件. \n\n");
	printf("请输入需要解密文件的名称: ");
	fgets(szSource, 100, stdin);
	if(szSource[strlen(szSource)-1] == '\n')
		 szSource[strlen(szSource)-1] = '\0';
	printf("请输入要输出文件的名称: ");
	fgets(szDestination, 100, stdin);
	if(szDestination[strlen(szDestination)-1] == '\n')
		 szDestination[strlen(szDestination)-1] = '\0';
	printf("加密这个文件时是否使用了密码? ( y/n ) ");
	response = getchar();
	if(response == 'y')
	{
		getchar();
		printf("请输入密码:");		
		gets(szPassword);
	}
	else
	{
		printf("密钥将被生成但没有使用密码. \n");
	}
	//解密文件
	if(!DecryptFile(szSource, szDestination, szPassword))
	{
		printf("\nError decrypting file. \n"); 
	}
	else
	{ 
		printf("\n对文件 %s 的解密成功了. \n", szSource);
		printf("被解密的文件是 %s .\n",szDestination);
	}
	//--------------------------------------------------------------------
	// 释放内存空间.
	if(szSource)
		 free(szSource);
	if(szDestination)
		 free(szDestination);

} // End main

//-------------------------------------------------------------------
// 功能:解密密文szSource文件,解密后的数据存储在szDestination文件中
// 参数:
//  szSource:密文文件名
//  szDestination:解密后数据存储文件
//  szPassword:用户输入的密码

static BOOL DecryptFile(
     PCHAR szSource, 
     PCHAR szDestination, 
     PCHAR szPassword) 
{ 
	//--------------------------------------------------------------------
	// 局部变量申明与初始化.

	FILE *hSource; 
	FILE *hDestination; 

	HCRYPTPROV hCryptProv; 
	HCRYPTKEY hKey; 

	PBYTE pbBuffer; 
	DWORD dwBlockLen; 
	DWORD dwBufferLen; 
	DWORD dwCount; 

	BOOL status = FALSE; 
 
	//--------------------------------------------------------------------
	// 打开密文文件. 
	if(!(hSource = fopen(szSource,"rb"))) 
	{
	   HandleError("打开密文文件出错!");
	}
	//--------------------------------------------------------------------
	// 打开目标文件,用于存储解密后的数据. 

	if(!(hDestination = fopen(szDestination,"wb")))
	{
		HandleError("打开明文文件出错!");
	}
	
	//获取加密服务者句柄
	hCryptProv = GetCryptProv();

	//获取或创建会话密钥
	if(!szPassword|| strcmp(szPassword,"")==0 ) 
	{ 
		//--------------------------------------------------------------------
		//从密文文件导入保存的会话密钥 

		hKey = GenKeyFromFile( hCryptProv,hSource);
		
	} 
	else 
	{ 
		//--------------------------------------------------------------------
		// 通过输入密码重新创建会话密钥. 
 
		hKey=GenKeyByPassword( hCryptProv, szPassword);
	} 
 

	// 计算一次解密的数据长度,它是ENCRYPT_BLOCK_SIZE 的整数倍

	dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; 
	dwBufferLen = dwBlockLen; 

	//--------------------------------------------------------------------
	// 分配内存空间. 

	if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
	{
	   HandleError("所需内存不够!\n"); 
	}
	//--------------------------------------------------------------------
	// 解密密文文件,解密后数据保存在目标文件 

	do { 
		//--------------------------------------------------------------------
		// 每次从密文文件中读取dwBlockLen字节数据. 

		dwCount = fread(
			 pbBuffer, 
			 1, 
			 dwBlockLen, 
			 hSource); 
		if(ferror(hSource))
		{
			HandleError("读取密文文件出错!");
		}
		//--------------------------------------------------------------------
		// 解密 数据
		if(!CryptDecrypt(
			  hKey, 
			  0, 
			  feof(hSource), 
			  0, 
			  pbBuffer, 
			  &dwCount))
		{
		   HandleError("Error during CryptDecrypt!"); 
		}
		//--------------------------------------------------------------------
		// 把解密后的数据写入目标文件中. 

		fwrite(
			pbBuffer, 
			1, 
			dwCount, 
			hDestination); 
		if(ferror(hDestination))
		{
		   HandleError("Error writing plaintext!"); 
		}
	} 	while(!feof(hSource)); 

	status = TRUE; 

	//--------------------------------------------------------------------
	// 关闭文件
	if(hSource)
	{
		if(fclose(hSource))
			HandleError("关闭原文件出错");
	}
	if(hDestination)
	{
		if(fclose(hDestination))
			HandleError("关闭目标文件出错");
	} 
 
	//--------------------------------------------------------------------
	// 释放内存空间 

	if(pbBuffer) 
		 free(pbBuffer); 
 
	//--------------------------------------------------------------------
	// 销毁会话密钥

	if(hKey)
	{
		if(!(CryptDestroyKey(hKey)))
			HandleError("Error during CryptDestroyKey");
	} 

	//--------------------------------------------------------------------
	// 释放CSP句柄
	if(hCryptProv)
	{
		if(!(CryptReleaseContext(hCryptProv, 0)))
			HandleError("Error during CryptReleaseContext");
	} 

	return status;
} // end Decryptfile


//获取加密提供者句柄
HCRYPTPROV GetCryptProv()
{
	HCRYPTPROV hCryptProv;                      // 加密服务提供者句柄
	
	//获取加密提供者句柄
	if(CryptAcquireContext(
				&hCryptProv,         // 加密服务提供者句柄
				NULL,                // 密钥容器名,这里使用登陆用户名
				MS_ENHANCED_PROV,         // 加密服务提供者     
				PROV_RSA_FULL,       // 加密服务提供者类型,可以提供加密和签名等功能
				0))                  // 标志
	{
		printf("加密服务提供者句柄获取成功!\n");
	}
	else
	{
		
		//重新建立一个新的密钥集
	    if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
		{
		   HandleError("重新建立一个新的密钥集出错!");
		}
 
	}
	return hCryptProv;
}


//  HandleError:错误处理函数,打印错误信息,并退出程序
void HandleError(char *s)
{
    printf("程序执行发生错误!\n");
    printf("%s\n",s);
    printf("错误代码为: %x.\n",GetLastError());
    printf("程序终止执行!\n");
    exit(1);
}

// GenKeyFromFile:从密文文件中导出会话密钥
// 参数:hCryptProv CSP句柄
//       hSource   保存会话密钥的文件
HCRYPTKEY GenKeyFromFile(HCRYPTPROV hCryptProv,FILE* hSource)
{
	HCRYPTKEY hKey; 

	PBYTE pbKeyBlob; 
	DWORD dwKeyBlobLen; 

	//从密文文件中获取密钥数据块长度,并分配内存空间. 
	fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource); 
	if(ferror(hSource) || feof(hSource))
	{
		HandleError("读取密文文件中密钥数据块长度出错!"); 
	}
	if(!(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen)))
	{
		HandleError("内存分配出错."); 
	}
	//--------------------------------------------------------------------
	// 从密文文件中获取密钥数据块

	fread(pbKeyBlob, 1, dwKeyBlobLen, hSource); 
	if(ferror(hSource) || feof(hSource))
	{
		HandleError("读取密文文件中密钥数据块出错!\n"); 
	}
	//--------------------------------------------------------------------
	// 导入会话密钥到 CSP. 
	if(!CryptImportKey(
		  hCryptProv, 
		  pbKeyBlob, 
		  dwKeyBlobLen, 
		  0, 
		  0, 
		  &hKey))
	{
	   HandleError("Error during CryptImportKey!"); 
	}

	if(pbKeyBlob) 
		free(pbKeyBlob);
	
	//返回导出的会话密钥
	return hKey;
}

// GenKeyByPassword:通过输入密码创建会话密钥
// 参数:hCryptProv CSP句柄
//       szPassword 输入密码
HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword)
{
	HCRYPTKEY hKey; 
	HCRYPTHASH hHash;
	//-------------------------------------------------------------------
	// 创建哈希句柄.  

	if(CryptCreateHash(
		   hCryptProv, 
		   CALG_MD5, 
		   0, 
		   0, 
		   &hHash))
		{
			printf("一个哈希句柄已经被创建. \n");
		}
		else
		{ 
			 HandleError("Error during CryptCreateHash!\n");
		}  
	//-------------------------------------------------------------------
	// 计算输入密码的哈希值. 

	if(CryptHashData(
		   hHash, 
		   (BYTE *)szPassword, 
		   strlen(szPassword), 
		   0))
	 {
		printf("此密码已经被添加到了哈希表中. \n");
	 }
	 else
	 {
		HandleError("Error during CryptHashData. \n"); 
	 }
	//-------------------------------------------------------------------
	// 通过哈希值创建会话密钥.

	if(CryptDeriveKey(
		   hCryptProv, 
		   ENCRYPT_ALGORITHM, 
		   hHash, 
		   KEYLENGTH, 
		   &hKey))
	 {
	   printf("从这个密码的哈希值获得了一个加密密钥. \n"); 
	 }
	 else
	 {
	   HandleError("Error during CryptDeriveKey!\n"); 
	 }
	//-------------------------------------------------------------------
	// 销毁哈希句柄. 

	if(hHash) 
	{
		if(!(CryptDestroyHash(hHash)))
		   HandleError("Error during CryptDestroyHash"); 
		hHash = 0;
	}
		
	//返回创建的会话密钥
	return hKey;
}


 

 

 


原文链接: http://blog.csdn.net/yincheng01/article/details/7080473

你可能感兴趣的:(vc++网络安全编程范例(17)-open ssl 实现文件加密与解密)