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

📄 filecodec.cpp

📁 用AES 加解密文件,内容包括一个测试EXE,和加解密模块D
💻 CPP
字号:
#ifndef DLL_FILE
#define DLL_FILE
#endif

#include "stdafx.h"
#include "DES.h"
#include "FileCodec.h"
#include "MD5Checksum.h"

int compare(unsigned char a[],unsigned char b[], int lenth)
{
	int i;
	for(i=0;i<lenth;i++)
		if(a[i]!=b[i])
			break;
	if(i==lenth)
		return 0;
	else
	    return (int (a[i]));
}

int GetBufValidLenth(char buff[] , int lenth)
{
	int i;
	for(i=lenth-1;i>=0; i--)
	{
		if(buff[i]!='\0')
			return (i+1);
	}
	return 0;
}


BOOL IsRoot(LPCTSTR lpszPath) 
{ 
	TCHAR szRoot[4]; 
	wsprintf(szRoot, "%c:\\", lpszPath[0]); 
	return (lstrcmp(szRoot, lpszPath) == 0); 
} 

CFileCodec::CFileCodec(void)
{
	lpcsEncCode[0]=0x3c;
	lpcsEncCode[1]=0xd6;
	lpcsEncCode[2]=0x78;
	lpcsEncCode[3]=0x66;
	lpcsEncCode[4]=0x20;
	lpcsEncCode[5]=0x06;
	lpcsEncCode[6]=0x88;
	lpcsEncCode[7]=0x88;
	lpcsEncCode[8]=0x7f;
	lpcsEncCode[9]=0x5a;
	lpcsEncCode[10]=0xbc;
	lpcsEncCode[11]=0x05;
	lpcsEncCode[12]=0x2c;
	lpcsEncCode[13]=0x55;
	lpcsEncCode[14]=0xeb;
	lpcsEncCode[15]=0x90;
}

CFileCodec::~CFileCodec(void)
{
}

void CFileCodec::DecStr(CString m_key, CString m_enc, CString &m_plain)
{
    char skey[32];
    char inbuff[32],oubuff[32];
	memset(skey,'\0',sizeof(skey));
	memcpy(skey,(LPCTSTR)m_key,m_key.GetLength());
	memcpy(inbuff,(LPCTSTR)m_enc,m_enc.GetLength());

	CString strTmp,str;
	DES jm	;

	jm.Des_Go(oubuff, inbuff, sizeof(inbuff),skey, sizeof(skey),  DECRYPT);

	for(int i=0;i<m_enc.GetLength();i++)
	  str +=oubuff[i];

    m_plain=str;
}

void CFileCodec::EncStr(CString m_key,CString m_plain, CString &m_enc)
{
    char skey[32];
    char inbuff[32],oubuff[32];
	memset(skey,'\0',sizeof(skey));
	memcpy(skey,(LPCTSTR)m_key,m_key.GetLength());
	memcpy(inbuff,(LPCTSTR)m_plain,m_plain.GetLength());

	CString str;

	DES jm;
	jm.Des_Go(oubuff, inbuff, sizeof(inbuff), skey,sizeof(skey), ENCRYPT);

	for(int i=0;i<32;i++)
	  str+=oubuff[i]; 

	m_enc=str;
}

int CFileCodec::DecFile(CString m_filekey, CString target_file,CString &errMsg)
{
	if(target_file=="") return -1;
    CFile ff(target_file,CFile::modeRead);

	if(IsEncFile(ff))
	{
		//获取文件长度
		int const minUnit = 8;
		long lFileLen = ff.GetLength()-32;
		if(lFileLen<=0)
		{
			errMsg="文件可能已损坏或未经AES加密过";
			return -1;
		}
		long c=lFileLen/minUnit;
		long d=lFileLen%minUnit;

		//获取checksum
		ff.Seek(16,CFile::begin);
		BYTE lpszMD5[16];
		ff.Read(lpszMD5,16);

		CString tmp_file = target_file + ".tmp";
		CFile fp(tmp_file,CFile::modeCreate|CFile::modeReadWrite);
		fp.SeekToBegin();

		 DES jm;
		 char inbuff[minUnit],oubuff[minUnit],skey[8];
		 memset(skey,'\0',sizeof(skey));
		 memcpy(skey,(LPCTSTR)m_filekey,8);

		 CTime tm1,tm2;
		 tm1=CTime::GetCurrentTime();
		//块解密
		for(long i=0;i<c-1;i++)
		{
			ff.Read(inbuff,minUnit);
			jm.Des_Go(oubuff, inbuff, sizeof(inbuff), skey,sizeof(skey), DECRYPT);
			fp.Write(oubuff,minUnit);
		}
		ff.Read(inbuff,minUnit);
		jm.Des_Go(oubuff, inbuff, sizeof(inbuff), skey,sizeof(skey), DECRYPT);
		fp.Write(oubuff,GetBufValidLenth(oubuff,minUnit));
		if(d>0)
		{
			errMsg="文件可能已损坏或未经AES加密过";
			ff.Close();
			fp.Close();
			return -1;
		}

		tm2=CTime::GetCurrentTime();
		CTimeSpan tmSpan=tm2-tm1;
		long strspan=tmSpan.GetTotalSeconds();

		ff.Close();

		//获取解密后文件checksum
		fp.Flush();
		fp.SeekToBegin();
		BYTE lpszCheckedMD5[16]; 
		CMD5Checksum::GetMD5(fp,lpszCheckedMD5,16);
		fp.Close();

		if(compare(lpszCheckedMD5,lpszMD5,16)!=0)
		{
			errMsg="密码错误";
			return -1;
		}

		DelFile(target_file);
		CFile::Rename(tmp_file,target_file);

		return strspan;
	}
	else
	{
		errMsg="文件是非加密文件";
		return 0;
	}
}

int CFileCodec::EncFile(CString m_filekey,CString target_file,CString &errMsg)
{
	if(target_file=="") return -1;

	CFile ff(target_file,CFile::modeRead);
	if(!IsEncFile(ff))
	{
		//获取checksum
		BYTE lpszMD5[16];
		CMD5Checksum::GetMD5(ff,lpszMD5,16);

		//获取文件长度并分块
		int const minUnit = 8;
		long lFileLen=ff.GetLength();
		long c=lFileLen/minUnit;
		long d=lFileLen%minUnit;

		CString tmp_file = target_file + ".tmp";
		CFile fp(tmp_file,CFile::modeCreate|CFile::modeWrite);

		ff.SeekToBegin();
		fp.SeekToBegin();

		DES jm;
		char inbuff[minUnit],oubuff[minUnit],skey[8];

		memset(skey,'\0',sizeof(skey));
		memcpy(skey,(LPCTSTR)m_filekey,8);

		CTime tm1,tm2;
		tm1=CTime::GetCurrentTime();

		//保存密文标志码到文件头16字节
		fp.Write(lpcsEncCode,16);

		//保存checksum到文件16——31字节
		fp.Write(lpszMD5,16);

		//块加密文件
		for(long i=0;i<c;i++)
		{
			ff.Read(inbuff,minUnit);
			jm.Des_Go(oubuff, inbuff, sizeof(inbuff), skey, sizeof(skey), ENCRYPT);
			fp.Write(oubuff,minUnit);
		}
		if(d>0)
		{
			memset(inbuff,'\0',sizeof(inbuff));
			ff.Read(inbuff,d);
			jm.Des_Go(oubuff, inbuff, sizeof(inbuff), skey,sizeof(skey), ENCRYPT);
			fp.Write(oubuff,minUnit);
		}
		tm2=CTime::GetCurrentTime();
		CTimeSpan tmSpan=tm2-tm1;
		long strspan = tmSpan.GetTotalSeconds();

		ff.Close();
		fp.Close();

		DelFile(target_file);
		CFile::Rename(tmp_file,target_file);

	    return strspan;
	}
	else
	{
		errMsg="文件已加过密";
	    return 0;
	}
}

void CFileCodec::DelFile(CString target_file)
{
	char *hDelFile;
	hDelFile = target_file.GetBuffer(target_file.GetLength());
	DeleteFile(hDelFile);
}

bool CFileCodec::IsEncFile(CFile &file)
{
	file.SeekToBegin();
	if(file.GetLength()<=16)
		return false;
	unsigned char buf[16];
	file.Read(buf,16);
	file.SeekToBegin();
	if(compare(lpcsEncCode , buf , 16) == 0 )
		return true;
	else
		return false;
}

int CFileCodec::EncDir(CString m_key, CString lpszPath, CString szfSuffix, CString &errMsg)
{
	return Recursive(m_key, lpszPath, szfSuffix, ENCRYPT, errMsg);
}

int CFileCodec::DecDir(CString m_key, CString lpszPath, CString szfSuffix, CString &errMsg)
{
	return Recursive(m_key, lpszPath, szfSuffix, DECRYPT, errMsg);
}


int CFileCodec::Recursive(CString m_key, CString lpszPath, CString szfSuffix, boolean type, CString &errMsg)
{
	CFileFind ff;
	CString szDir = lpszPath;
	if(szDir.Right(1) != "\\")
		szDir += "\\";	
	szDir += "*.*";
	
	BOOL res = ff.FindFile(szDir);
	while(res)
	{
		res = ff.FindNextFile();
		if(ff.IsDirectory() && !ff.IsDots())
		{
			//如果是一个子目录,用递归继续往深一层找
			CString strPath = ff.GetFilePath();
			Recursive(m_key, strPath, szfSuffix, type, errMsg);
		}
		else if(!ff.IsDirectory() && !ff.IsDots())
		{
			//显示当前访问的文件
			CString strPath = ff.GetFilePath();
			CString lzsFileExt = strPath.Right( strPath.GetLength() - strPath.Find(".",0) -1 );
			if( strcmp(lzsFileExt,szfSuffix) == 0 )
			{
				if(type==ENCRYPT){
					if(EncFile(m_key, strPath, errMsg) == -1)
						return -1;
				}
				else			
				{	if(DecFile(m_key, strPath, errMsg) == -1)
						return -1;
				}
			}
		}
	}
	ff.Close();
	return 0;
}
/*

void CFileCodec::Recursive(CString m_key, CString lpszPath, CString szfSuffix, boolean type)
{
	BOOL brecursive;
	TCHAR szFind[MAX_PATH];
	lstrcpy(szFind, lpszPath);
	if (!IsRoot(szFind))
		lstrcat(szFind, "\\"); 
	lstrcat(szFind, "*.*"); // 找所有文件
	WIN32_FIND_DATA wfd; 
	HANDLE hFind = FindFirstFile(szFind, &wfd); 
	if (hFind == INVALID_HANDLE_VALUE) // 如果没有找到或查找失败 
	return; 

	do 
	{
		if (wfd.cFileName[0] == '.')
			continue; // 过滤这两个目录
		if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			TCHAR szFile[MAX_PATH];
			if(IsRoot(lpszPath))
				wsprintf(szFile, "%s%s", lpszPath, wfd.cFileName);
			else
				wsprintf(szFile, "%s\\%s", lpszPath, wfd.cFileName);
			Recursive(m_key, szFile, szfSuffix, type);
		}
		else
		{
			TCHAR szFile[MAX_PATH];
			CString lzsFileExt = wfd.cFileName;
			lzsFileExt = lzsFileName.Right( lzsFileName.Getlenth() - lzsFileName.Find(".",0) -1 );
			if( strcmp(lzsFileExt,szfSuffix) == 0 )
			{
				if (IsRoot(lpszPath))
					wsprintf(szFile, "%s%s", lpszPath, wfd.cFileName);
				else
					wsprintf(szFile, "%s\\%s", lpszPath, wfd.cFileName);

				// 对文件进行操作
				printf("%s\n",szFile);
				if(type==ENCRYPT)
					EncFile(m_key,sFileName, errMsg);
				else			
					DecFile(m_key, sFileName,errMsg);
			}
		}
	}
	while(FindNextFile(hFind, &wfd));

	FindClose(hFind); // 关闭查找句柄
}
*/

⌨️ 快捷键说明

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