⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cryptapicommon.cpp

📁 CryptAPI 演示程序
💻 CPP
字号:
#include "stdafx.h"
#include "CryptAPICommon.h"

 BOOL EncryptFileX(
						LPWSTR szSource,        // 明文
						LPWSTR szDestination,   // 密文
						PCHAR szPassword)      // 通信字
						//--------------------------------------------------------------------
						//     Parameters passed are:   函数所传递的参数如下:
						//     szSource, the name of the input, a plaintext file.
						//输入文件即明文文件的名字
						//     szDestination, the name of the output, an encrypted file to be 
						//     created.        输出文件即已加密文件的名字
						//     szPassword, the password.   通行字
{ 
	//--------------------------------------------------------------------
	//   Declare and initialize local variables.  对局部变量进行说明和初始化

	    CFile hSource;          //明文位置
		CFile hDestination;     //密文位置

		HCRYPTPROV hCryptProv;  //提供者句柄
		HCRYPTKEY  hKey;        //密钥句柄
		HCRYPTHASH hHash;       //HASH句柄

		PBYTE pbBuffer;         //缓冲区
		DWORD dwBlockLen;       //分组长度
		DWORD dwBufferLen;      //缓冲区长度
		DWORD dwCount;          

		////--------------------------------------------------------------------
		//// Open source file.     //为读打开源文件
		//if (hSource = fopen(
		//szSource,  //源文件名
		//"rb"))     //打开属性(即目的为读)
		//	{  //如果打开源文件成功,
		//		printf("The source plaintext file, %s, is open. \n", szSource);
		//			//则打印:源明文文件XXX已经被打开
		//	}
		//	 else
		//	 {  //如果打开源文件失败,
		//		 HandleError("Error opening source plaintext file!");
		//			 //则差错处理:打开源明文文件出错
		//	 } 

//-------------************************打开明文文件*****************----------------------------------------------------------
       CFileException ex;
	   CFileFind fn;
	   if(!fn.FindFile(szSource))
		   return FALSE;
	   
//szSource
	   if(!hSource.Open(szSource,CFile::modeReadWrite ,&ex))
		{
			HandleError("文件打开失败!");
			return FALSE;

		}

//**********创建加密文件************************************

		//if(!hDestination.Open(szDestination, CFile::modeCreate|CFile::modeWrite),&ex)
		//{
		//	HandleError("保存文件失败!");
		//	return FALSE;

		//}

		if(!hDestination.Open(szDestination,CFile::modeWrite| CFile::modeCreate,&ex))
		{
			HandleError("保存文件失败!");
			return FALSE;

		}

	 //--------------------------------------------------------------------
	 // Open destination file.    打开目的文件
	 //if (hDestination = fopen(
		// szDestination,  //目的文件名
		// "wb"))          //打开属性(即目的)
		// {  //如果打开目的文件成功,
		//	 printf("Destination file %s is open. \n", szDestination);
		//		 //则打印:目的文件XXX已经打开
		// }
	 //else
		// {  //如果打开目的文件失败,
		//	 HandleError("Error opening destination ciphertext file!"); 
		//		 //则差错处理:打开目的文件XXX出错
		// }
 //========================================================
 //以下获得一个CSP句柄
	 if (CryptAcquireContext(
		 &hCryptProv,   // 返回CSP句柄
		 NULL,         //NULL表示使用默认密钥容器,默认密钥容器名为用户登陆名
		 NULL,          // NULL时使用默认CSP名(微软RSA Base Provider)
		 PROV_RSA_FULL, // CSP类型
		 0))            // Flag values
	 {  //如果获得CSP句柄成功,
		 printf("A cryptographic provider has been acquired. \n");
		 //则打印:密码提供者已经获得
	 }
	 else
	 {  //如果获得CSP句柄失败,则创建一个新的密钥容器
		 if(CryptAcquireContext(
			 &hCryptProv,      // 返回CSP句柄
			 NULL,             // 密钥容器名
			 NULL,             // NULL时使用默认CSP名(微软RSA Base Provider)
			 PROV_RSA_FULL,    // CSP类型
			 CRYPT_NEWKEYSET)) // Flag values
			 //以上函数用于创建新的密钥容器
		 {   //如果创建密钥容器成功,并得到CSP句柄,则打印:新的密钥容器已经创建成功
			 printf("A new key container has been created.\n");
		 }
		 else
		 {   //如果创建密钥容器失败,则打印:未能创建新的密钥容器
			 HandleError("Could not create a new key container.\n");
		 }
	 }

 //--------------------------------------------------------------------
 //   创建一个会话密钥(session key)。会话密钥也叫对称密钥,用于对称加密。
 //   一个Session是指从调用函数CryptAcquireContext到调用函数
 //   CryptReleaseContext期间的交互阶段。会话密钥只能存在于一个会话过程。会话//   密钥是通过把通行字散列再导出的。如下所述:
 //--------------------------------------------------------------------
 // Create a hash object.   创建一个HASH对象
	 if (CryptCreateHash( //创建一个HASH对象
		 hCryptProv,   //CSP句柄(即标识)
		 CALG_MD5,     //哈希算法的标识符。
		 0,            //密钥句柄(即标识)
		 0,            //保留。必须为0。
		 &hHash))      //哈希对象的句柄(即标识),以后就用这个句柄。
	 {   //如果创建HASH对象成功,
		 printf("A hash object has been created. \n");
		 //则打印:HASH对象创建成功
	 }
	 else
	 {   //如果创建HASH对象失败,
		 HandleError("Error during CryptCreateHash!\n");
		 //出错处理:创建HASH对象时出错
	 }  

	//--------------------------------------------------------------------
	// 对输入的通信字进行散列得到的散列结果仍放在通行字位置上。
	 if (CryptHashData(   //对通信字进行HASH
		 hHash,             //哈希对象的句柄(即标识)
		 (BYTE *)szPassword,//要加入到哈希对象的通行字的指针(即要HASH的数据)
		 strlen(szPassword),//数据长度(即要HASH的通行字的长度-字节数)
		 0))                //标志
	 {  //如果对通行字HASH成功,
		 printf("The password has been added to the hash. \n");
		 //则打印:通行字已经被加到HASH中
	 }
	 else
	 {  //如果对通行字HASH失败,
		 HandleError("Error during CryptHashData. \n"); 
		 //则出错处理:对数据进行HASH时出错
	 }

 //--------------------------------------------------------------------
 // 通过散列生成会话密钥
	 if(CryptDeriveKey(  // 通过散列生成会话密钥
		 hCryptProv,         //CSP句柄(即标识)(入)
		 ENCRYPT_ALGORITHM,  //要产生密钥的对称加密算法(入)
		 hHash,              //哈希对象的句柄(即标识),通行字的散列已在其中(入)
		 KEYLENGTH,          //指定密钥的长度(入)
		 &hKey))             //密钥的句柄(即标识)(出)
	 {  //如果通过散列生成会话密钥成功,
		 printf("An encryption key is derived from the password hash. \n"); 
		 //则打印:加密密钥已经从HASH对象的通行字散列中导出。
	 }
	 else
	 {  //如果通过散列生成会话密钥失败,
		 HandleError("Error during CryptDeriveKey!\n"); 
		 //则差错处理:导出密钥时出错。
	 }
 //--------------------------------------------------------------------
 // Destroy the hash object.    销毁HASH对象
	 CryptDestroyHash(hHash);  //参数为HASH对象的句柄
	 hHash = NULL;             //此后该句柄不可再用了。

	 //--------------------------------------------------------------------
	 //  The session key is now ready. 现在会话密钥已经准备好了。

	 //--------------------------------------------------------------------
	 // 因为加密算法是按ENCRYPT_BLOCK_SIZE 大小的分组加密的,所以被加密的
	 // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的数据长度。

	 dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; 

	 //--------------------------------------------------------------------
	 // Determine the block size. If a block cipher is used, 
	 //如果使用分组密码,就确定分组的大小。
	 // it must have room for an extra block. 

	 if (ENCRYPT_BLOCK_SIZE > 1) 
		 dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; 
	 else 
		 dwBufferLen = dwBlockLen; 

 //--------------------------------------------------------------------
 // Allocate memory.   分配内存
	 if (pbBuffer = (BYTE *)malloc(dwBufferLen))
	 {  //如果按指定长度分配内存成功,
		 printf("Memory has been allocated for the buffer. \n");
		 //则打印:已经为缓冲区分配了内存。
	 }
	 else
	 {  //如果按指定长度分配内存失败,
		 HandleError("Out of memory. \n"); 
		 //则出错处理:
	 }
 //--------------------------------------------------------------------
 // In a do loop, encrypt the source file and write to the source file. 
 // 做Do循环,对源文件进行加密,并写入源文件。
	 DWORD dwRead=0;
	 do 
	 { 
		 //--------------------------------------------------------------------
		 // Read up to dwBlockLen bytes from the source file.
		 // 以下从源文件读出指定长度的字节,
		// dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
		dwRead= hSource.Read(pbBuffer,dwBlockLen);
		//DWORD dwDataLen=sizeof(pbBuffer);
		//dwCount=dwDataLen;
		 //从源文件中读出指定长度的字节,并写入指定的缓冲区。
		 //if(ferror(hSource))
		 //{ 
			// HandleError("Error reading plaintext!\n");
		 //}

		 //--------------------------------------------------------------------
		 // 加密数据
		 if (!CryptEncrypt(    //对数据进行加密
			 hKey,           //加密密钥的句柄
			 0,              //HASH对象的句柄,如果数据同时进行散列和加密
			 (dwRead<dwBlockLen),  //是否是最后一次加密操作
			 //如果是最后一次加密操作,则输入TRUE;
			 //如果不是,则输入FALSE。
			 //这里通过判断是否到文件尾来决定是否为最后一块。
			 0,              //保留
			 pbBuffer,       //待加密的数据区,已加密的数据区
			 &dwRead,       //待加密的数据长度,已加密的数据长度
			 dwBufferLen))   //pbBuffer的大小。
		 {  //如果对数据进行加密失败,
			 HandleError("Error during CryptEncrypt. \n"); 
			 //则出错处理:数据加密时出错。
		 } 

		 //--------------------------------------------------------------------
		 // Write data to the destination file. 把数据写入目的文件

		 //fwrite(pbBuffer, 1, dwCount, hDestination);
		 hDestination.Write(pbBuffer,dwBufferLen);
		 //把pbBuffer中的已加密数据写入目的文件中。
		
	 } 
	 while(dwRead>0);  //循环,直到以hSource为句柄的文件到达末尾时跳出循环。
	 //--------------------------------------------------------------------
	 //  End the do loop when the last block of the source file has been
	 //  当源文件的最后一块已经被读出、加密、写入目的文件时结束Do循环。
	 //  read, encrypted, and written to the destination file.

	 //--------------------------------------------------------------------
	 // Close files.关闭文件

	 if (hSource)                   //如果源文件的句柄存在,
		 hSource.Close();      //则关闭该源文件

	 if(hDestination)   
	 {//如果目的文件的句柄存在,
		 hDestination.Flush();
		 hDestination.Close(); //则关闭该目的文件
	 }
	 //--------------------------------------------------------------------
	 // Free memory.                释放内存

	 if(pbBuffer)              //如果变量名为pbBuffer的缓冲区存在,
		 free(pbBuffer);  //则释放该缓冲区。

	 //--------------------------------------------------------------------
	 // Destroy session key.   //销毁会话密钥

	 if(hKey)                        //如果句柄为hKey的密钥存在,
		 CryptDestroyKey(hKey); //则销毁该密钥

	 //--------------------------------------------------------------------
	 // Destroy hash object.   销毁HASH对象

	 if(hHash)                         //如果句柄为hHash的HASH对象存在,
		 CryptDestroyHash(hHash); //则销毁该HASH对象。

	 //--------------------------------------------------------------------
	 // Release provider handle. 释放提供者句柄。

	 if(hCryptProv)                               //如果提供者句柄存在,
		 CryptReleaseContext(hCryptProv, 0); //则释放该提供者。
   // HandleError("加密成功!");
	 return(TRUE); 
} // End of Encryptfile



//***************************错误处理*************************************
void HandleError(char *s)
{
	//fprintf(stderr,"An error occurred in running the program. \n");
	//	fprintf(stderr,"%s\n",s);
	//	fprintf(stderr, "Error number %x.\n", GetLastError());
	//	fprintf(stderr, "Program terminating. \n");
	CString strInfo;
	strInfo=s;
	AfxMessageBox(strInfo);
		return;
} // End of HandleError

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -