📄 文件保险箱dlg.cpp
字号:
#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 + -