📄 cryptapicommon.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 + -