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

📄 文件保险箱dlg.cpp

📁 安全文件柜,使用CryptApi接口实现.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#ifdef _DEBUG
	AfxMessageBox(strPass);
#endif
	if(Decrypt_File(strCipherFilePath,strPlainFilePath,strPass))
	{
		AfxMessageBox("解密文件成功");
	}
	else
	{
		AfxMessageBox("解密文件失败");
	}	
}
 
/**********************************************************************
函数名称:Encrypt_File
函数功能:加密文件
处理过程:
	1.根据选择的密码算法以及口令,生成用于加密数据的会话密钥
	2.把密码算法作为文件头写到密文。
	3.循环读取原文文件数据加密后保存到密文文件路径中。
参数说明:
	strPstrPlainFilePath:[IN] CString,待加密的原文文件路径
	strCipherFilePath:[IN] CString,加密后的密文文件保存路径
	nAlg_ID:[IN] int 密码算法ID
	strPass:[IN] CString 口令
返回值:成功返回TRUE,否则返回FALSE	
************************************************************************/
BOOL CMyDlg::Encrypt_File(CString strPlainFilePath, CString strCipherFilePath, DWORD nAlg_ID, CString strPass)
{
	FILE *hSource;			//保存打开明文文件的句柄
	FILE *hDestination;		//保存打开密文文件的句柄
	HCRYPTPROV hCryptProv;	//CSP句柄
	HCRYPTKEY hKey;			//加密文件的会话密钥句柄
 	HCRYPTHASH hHash;		//根据口令派生会话密钥的哈希对象
	PBYTE pbBuffer;			
	DWORD dwBlockLen; 
	DWORD dwBufferLen; 
	DWORD dwCount; 
	
	char *szSource= strPlainFilePath.GetBuffer(0);
	char *szDestination= strCipherFilePath.GetBuffer(0);
	char *szPassword =  strPass.GetBuffer(0);

	// 打开明文文件
	if(!(hSource = fopen(szSource,"rb")))
	{
	  return FALSE;
	}
	// 打开密文文件 
	if(!(hDestination = fopen(szDestination,"wb")))
	{
		return FALSE;
	}
	//打开 MS_ENHANCED_PROV CSP
	if(!CryptAcquireContext(
		  &hCryptProv, 
		  NULL, 
		  MS_ENHANCED_PROV, 
		  PROV_RSA_FULL, 
		  0))
	{
		fclose(hDestination);
		fclose(hSource);
		return FALSE;
	} 
	//使用口令派生出会话密钥来加密文件
	//创建摘要句柄
	if(!CryptCreateHash(
		   hCryptProv, 
		   CALG_MD5, 
		   0, 
		   0, 
		   &hHash))
	{
		fclose(hDestination);
		fclose(hSource);
		return FALSE;
	}
 	// 对口令进行摘要运算
	if(!CryptHashData(
		   hHash, 
		   (BYTE *)szPassword, 
		   strlen(szPassword), 
		   0))
	 {
		fclose(hDestination);
		fclose(hSource);
		return FALSE;
	 }
	//从哈希对象中派生出会话密钥
	if(!CryptDeriveKey(
		   hCryptProv, 
		   nAlg_ID, 
		   hHash, 
		   CRYPT_EXPORTABLE, 
		   &hKey))
	 {
		DWORD dwErr=GetLastError();
		fclose(hDestination);
		fclose(hSource);
		CryptDestroyHash(hHash); 
		CryptReleaseContext(hCryptProv, 0);
		return FALSE;
	 }
	//销毁哈希对象
	CryptDestroyHash(hHash); 
	hHash = 0; 
	DWORD dwEncBlockSize = 0;
	DWORD dwTmp;
	//获得会话密钥参数
	if(!CryptGetKeyParam(hKey,KP_BLOCKLEN,(BYTE *)&dwEncBlockSize,&dwTmp,0))
	{
		CryptDestroyKey(hKey); 
		CryptReleaseContext(hCryptProv, 0);
		return FALSE;
	}
 	//现在加密文件的会话密钥已经准备好了。
	dwBlockLen = 1000 - 1000 % dwEncBlockSize; 
	if(dwEncBlockSize > 1) 
		dwBufferLen = dwBlockLen + dwEncBlockSize; 
	else 
		dwBufferLen = dwBlockLen; 
 	if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
	{
		fclose(hDestination);
		fclose(hSource);
		CryptDestroyHash(hHash); 
		CryptDestroyKey(hKey); 
		CryptReleaseContext(hCryptProv, 0);
		return FALSE;
	}
	char enchead[128]={0};
	sprintf(enchead,"ALGID:%d\n",nAlg_ID);
	fwrite(enchead,1,128,hDestination); 
	//不断循环加密原文件,把密文写入的密文文件
	do 
	{ 
		//读取原文dwBlockLen字节
		dwCount = fread(pbBuffer, 1, dwBlockLen, hSource); 
		if(ferror(hSource))
		{ 
			fclose(hDestination);
			fclose(hSource);
			CryptDestroyHash(hHash); 
			CryptDestroyKey(hKey); 
			CryptReleaseContext(hCryptProv, 0);
			return FALSE;
		}
 		//加密数据
		if(!CryptEncrypt(
			 hKey, 
			 0, 
			 feof(hSource), 
			 0, 
			 pbBuffer, 
			 &dwCount, 
			 dwBufferLen))
		{ 
			fclose(hDestination);
			fclose(hSource);
			CryptDestroyHash(hHash); 
			CryptDestroyKey(hKey); 
			CryptReleaseContext(hCryptProv, 0);
			return FALSE; 
		} 
		//把密文写入的密文文件
		fwrite(pbBuffer, 1, dwCount, hDestination); 
		if(ferror(hDestination))
		{ 
			fclose(hDestination);
			fclose(hSource);
			CryptDestroyHash(hHash); 
			CryptDestroyKey(hKey); 
			CryptReleaseContext(hCryptProv, 0);
			return FALSE;
		}
	} while(!feof(hSource)); 
	//加密完成,关闭文件句柄、释放内存、销毁会话密钥等
	if(hSource) 
		fclose(hSource); 
	if(hDestination) 
		fclose(hDestination); 
	if(pbBuffer) 
		 free(pbBuffer); 
	if(hKey) 
		CryptDestroyKey(hKey); 
	if(hHash) 
		CryptDestroyHash(hHash); 
	if(hCryptProv) 
		CryptReleaseContext(hCryptProv, 0);	
	return TRUE;
}
/**********************************************************************
函数名称:Decrypt_File
函数功能:对加密文件解密
处理过程:
	1.根据算法和口令派生出解密数据的会话密钥
	2.读取密文文件头,获取加密算法。
	2.循环读取原文文件数据解密,并保存在原文文件。
参数说明:
	strCipherFilePath:[IN] CString,密文文件路径
	strPstrPlainFilePath:[IN] CString,解密后的原文文件保存路径。
	strPass:[IN] CString 口令
返回值:成功返回TRUE,否则返回FALSE	
************************************************************************/

BOOL CMyDlg::Decrypt_File(CString strCipherFilePath, CString strPlainFilePath, CString strPass)
{
	FILE *hSource;			//保存打开密文文件的句柄
	FILE *hDestination;		//保存打开明文文件的句柄

	HCRYPTPROV hCryptProv;	//CSP句柄
	HCRYPTKEY hKey;			//解密文件的会话密钥句柄
	HCRYPTHASH hHash;		//根据口令派生会话密钥的哈希对象
	DWORD nAlg_ID;
	PBYTE pbKeyBlob = NULL; 
  
	PBYTE pbBuffer; 
	DWORD dwBlockLen; 
	DWORD dwBufferLen; 
	DWORD dwCount; 

	BOOL status = FALSE; 
	char *szSource=strCipherFilePath.GetBuffer(0);
	char *szDestination=strPlainFilePath.GetBuffer(0);
	char *szPassword=strPass.GetBuffer(0);
	// 打开密文文件
	if(!(hSource = fopen(szSource,"rb"))) 
	{
	   return status;
	}
	//打开目标文件即解密后的明文文件
	if(!(hDestination = fopen(szDestination,"wb")))
	{
		return status;
	} 
	//从密文文件头读取加密算法
	char enchead[128]={0};
	fread(enchead,1,128,hSource);
	sscanf(enchead,"ALGID:%d\n",&nAlg_ID); 
	// 获得CSP句柄
	if(!CryptAcquireContext(
		  &hCryptProv, 
		  NULL, 
		  MS_ENHANCED_PROV, 
		  PROV_RSA_FULL, 
		  0))
	{
	   return status;
	}
	 //利用口令派生出的会话密钥解密文件
	// 创建哈希对象
	if(!CryptCreateHash(
		   hCryptProv, 
		   CALG_MD5, 
		   0, 
		   0, 
		   &hHash))
	{
		return status;;
	}
	// 哈希口令
	if(!CryptHashData(
		   hHash, 
		   (BYTE *)szPassword, 
		   strlen(szPassword), 
		   0)) 
	{
		return status;; 
	}
	// 从哈希对象中派生出会话密钥
	if(!CryptDeriveKey(
		  hCryptProv, 
		  nAlg_ID, 
		  hHash, 
		  CRYPT_EXPORTABLE, 
		  &hKey))
	{ 
	   return status;
	}
	// 销毁哈希对象
	CryptDestroyHash(hHash); 
	hHash = 0; 
	//现在已经获得了解密数据的会话密钥。
	DWORD dwEncBlockSize = 0;
	DWORD dwTmp;
	CryptGetKeyParam(hKey,KP_BLOCKLEN,(BYTE *)&dwEncBlockSize,&dwTmp,0);
	dwBlockLen = 1000 - 1000 % dwEncBlockSize; 
	dwBufferLen = dwBlockLen; 
	if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
	{
	   return status;
	}
	// 解密密文,并把明文写到明文文件中。	
	do { 
	// 循环读取密文
	dwCount = fread(
		 pbBuffer, 
		 1, 
		 dwBlockLen, 
		 hSource); 
	if(ferror(hSource))
	{
		return status;
	}
	// 数据解密
	if(!CryptDecrypt(
		  hKey, 
		  0, 
		  feof(hSource), 
		  0, 
		  pbBuffer, 
		  &dwCount))
	{
	  return status;
	}
	// 写明文数据到文件
	fwrite(
		pbBuffer, 
		1, 
		dwCount, 
		hDestination); 
	if(ferror(hDestination))
	{
	   return status;
	}
	} 
	while(!feof(hSource)); 
	status = TRUE; 
	// 关闭文件
	if(hSource) 
	   fclose(hSource); 
	if(hDestination) 
		fclose(hDestination); 
 	// 解密完成,释放内存、关闭文件句柄、销毁会话密钥、CSP句柄等。
	if(pbKeyBlob) 
		 free(pbKeyBlob);
	if(pbBuffer) 
		 free(pbBuffer); 
	if(hKey) 
		CryptDestroyKey(hKey); 
	if(hHash) 
		CryptDestroyHash(hHash); 
	if(hCryptProv) 
		CryptReleaseContext(hCryptProv, 0); 
	return status;
}

⌨️ 快捷键说明

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