www.gusucode.com > VC++运用OpenSSL实现对文件加密源码程序 > VC++运用OpenSSL实现对文件加密源码程序\code\DlgEnc.cpp

    //Download by http://www.NewXing.com
// DlgEnc.cpp : implementation file
//

#include "stdafx.h"
#include "osslin.h"
#include "DlgEnc.h"
#include "OssLinDlg.h"
#include "Structs.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDlgEnc dialog


CDlgEnc::CDlgEnc(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgEnc::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgEnc)
	m_inPath = _T("");
	m_keyPath = _T("");
	m_key = _T("");
	m_outPath = _T("");
	m_keyOrder = -1;
	//}}AFX_DATA_INIT
}


void CDlgEnc::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgEnc)
	DDX_Control(pDX, IDC_LIST_INFOSHOW, m_infoList);
	DDX_Text(pDX, IDC_EDIT_ENC_INPATH, m_inPath);
	DDX_Text(pDX, IDC_EDIT_ENC_KEYPATH, m_keyPath);
	DDX_Text(pDX, IDC_EDIT_ENC_KEY, m_key);
	DDX_Text(pDX, IDC_EDIT_ENC_OUTPATH, m_outPath);
	DDX_Radio(pDX, IDC_RADIO_KEYORDER, m_keyOrder);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgEnc, CDialog)
	//{{AFX_MSG_MAP(CDlgEnc)
	ON_BN_CLICKED(IDC_BUT_INPATH, OnButInpath)
	ON_BN_CLICKED(IDC_BUT_KEYPATH, OnButKeypath)
	ON_BN_CLICKED(IDC_BUT_OUTPATH, OnButOutpath)
	ON_BN_CLICKED(IDC_BUT_ENC_GO, OnButEncGo)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgEnc message handlers
void CDlgEnc::SetEncInfo()
{
	UpdateData(TRUE);
	CComboBox * pCombo = (CComboBox *)GetDlgItem(IDC_COMBO_ENCWAY);
	m_encOrder = pCombo->GetCurSel();
}

void CDlgEnc::InitEnc()
{
	md=EVP_md5();
	EVP_CIPHER_CTX_init(&ctx);

	switch(m_encOrder)
	{
	case 0:
		cipher=EVP_aes_128_cbc();
		break;
	case 1:
		cipher=EVP_aes_128_cfb();
		break;
	case 2:
		cipher=EVP_aes_128_ecb();
		break;
	case 3:
		cipher=EVP_aes_128_ofb();
		break;
	case 4:
		cipher=EVP_aes_192_cbc();
		break;
	case 5:
		cipher=EVP_aes_192_cfb();
		break;
	case 6:
		cipher=EVP_aes_192_ecb();
		break;
	case 7:
		cipher=EVP_aes_192_ofb();
		break;
	case 8:
		cipher=EVP_aes_256_cbc();
		break;
	case 9:
		cipher=EVP_aes_256_cfb();	
		break;
	case 10:
		cipher=EVP_aes_256_ecb();
		break;
	case 11:
		cipher=EVP_aes_256_ofb();
		break;
	case 12:
		cipher=EVP_bf_cbc();
		break;
	case 13:
		cipher=EVP_bf_cfb();
		break;
	case 14:
		cipher=EVP_bf_ecb();
		break;
	case 15:
		cipher=EVP_bf_ofb();
		break;
	case 16:
		cipher=EVP_cast5_cbc();	
		break;
	case 17:
		cipher=EVP_cast5_cfb();	
		break;
	case 18:
		cipher=EVP_cast5_ecb();	
		break;
	case 19:
		cipher=EVP_cast5_ofb();
		break;
	case 20:
		cipher=EVP_des_cbc();
		break;
	case 21:
		cipher=EVP_des_cfb();
		break;
	case 22:
		cipher=EVP_des_ecb();
		break;
	case 23:
		cipher=EVP_des_ede_cbc();
		break;
	case 24:
		cipher=EVP_des_ede_cfb();
		break;
	case 25:
		cipher=EVP_des_ede();	
		break;
	case 26:
		cipher=EVP_des_ede_ofb();
		break;
	case 27:
		cipher=EVP_des_ede3_cbc();	
		break;
	case 28:
		cipher=EVP_des_ede3_cfb();	
		break;
	case 29:
		cipher=EVP_des_ede3();	
		break;
	case 30:
		cipher=EVP_des_ede3_ofb();	
		break;
	case 31:
		cipher=EVP_des_ofb();	
		break;
	case 32:
		cipher=EVP_desx_cbc();		
		break;
	case 33:
		cipher=EVP_idea_cbc();		
		break;	
	case 34:
		cipher=EVP_idea_cfb();		
		break;	
	case 35:
		cipher=EVP_idea_ecb();		
		break;	
	case 36:
		cipher=EVP_idea_ofb();		
		break;	
	case 37:
		cipher=EVP_rc2_cbc();		
		break;	
	case 38:
		cipher=EVP_rc2_cfb();		
		break;	
	case 39:
		cipher=EVP_rc2_ecb();		
		break;	
	case 40:
		cipher=EVP_rc2_ofb();	
		break;
	case 41:
		cipher=EVP_rc4();	
		break;
	case 42:
		cipher=EVP_rc4_40();	
		break;
	default:
		cipher=EVP_des_cbc();
		break;
	}

	int datal=0,count=2;
	long keyflen;
	int keylen=EVP_CIPHER_key_length(cipher);
	key=(BYTE *)malloc(sizeof(BYTE)*keylen);
	int ivlen=EVP_CIPHER_iv_length(cipher);
	iv=(BYTE *)malloc(sizeof(BYTE)*ivlen);

	if(m_keyOrder==0)
	{
		int datal=m_key.GetLength();
		BYTE * data=(BYTE *)malloc(sizeof(BYTE)*datal);
		strcpy((char *)data,m_key.GetBuffer(datal));
		EVP_BytesToKey(cipher,md,NULL,data,datal,count,key,iv);
	}
	else if(m_keyOrder==1)
	{
		FILE * keyf=fopen(m_keyPath,"r");
		fseek(keyf,0,SEEK_END);
		keyflen=ftell(keyf);
		unsigned char * data=(unsigned char *)malloc(sizeof(BYTE)*keyflen);
		datal=keyflen;
		fread(data,sizeof(BYTE),keyflen,keyf);
		EVP_BytesToKey(cipher,md,NULL,data,datal,count,key,iv);
	}
	EVP_EncryptInit_ex(&ctx,cipher,NULL,key,iv);
}

BYTE * CDlgEnc::Encrypt(BYTE * inBuff,int inLen,int & outLen)
{
	if(inLen <= 0)
	{
		outLen = 0;
		return NULL;
	}
	BYTE * outBuff;
	outBuff=(BYTE *)malloc((inLen+24)*sizeof(BYTE));
	int inl=0, lenout=0, outl=0,lenin=0;
	if(inLen<=48)
	{
		EVP_EncryptUpdate(&ctx,outBuff,&outl,inBuff,inLen);
		lenout+=outl;
		lenin=inLen;
	}
	else if(inLen>48)
	{
		while(lenin+48<inLen)
		{
			EVP_EncryptUpdate(&ctx,(outBuff+lenout),&outl,(inBuff+lenin),48);
			lenout+=outl;
			inl=48;
			lenin+=48;
		}
		EVP_EncryptUpdate(&ctx,(outBuff+lenout),&outl,(inBuff+lenin),inLen-lenin);
		lenout+=outl;
	}
	EVP_EncryptFinal_ex(&ctx,(outBuff+lenout),&outl);
	lenout+=outl;
	
	outBuff=this->Base64(0,outBuff,lenout);
	outLen=lenout;
	delete inBuff;
	return outBuff;
}


void CDlgEnc::ChoseFilePath(CString & filepath)
{
	CFileDialog fdlg(true);
	fdlg.m_ofn.lpstrTitle="选择路径";
	fdlg.m_ofn.lpstrFilter="Key Files(*.*)\0*.*\0All Files(*.*)\0*.*\0\0";
//	fdlg.m_ofn.lpstrDefExt="bmp";
	if(IDOK==fdlg.DoModal())
	{
		filepath = fdlg.GetPathName();
	}
}

BYTE* CDlgEnc::FileRead(CString fileName, int onceLen, long fpoint,long & outl)
{
	FILE * pf;
	long flen=0;
	pf=fopen(fileName,"rb");
	if(!pf)
	{
		MessageBox("打开文件错误");
		return NULL;
	}
	fseek(pf,0,SEEK_END);
	flen=ftell(pf);
	outl=flen;
	
	fseek(pf,fpoint,SEEK_SET);
	BYTE * buff = (BYTE *)malloc(sizeof(BYTE)*(onceLen+1));
	if(!buff)
	{
		MessageBox("申请内存失败");
		return NULL;
	}
	int size=fread(buff,sizeof(BYTE),onceLen,pf);
	fclose(pf);
	buff[size]='\0';
	return buff;
}

void CDlgEnc::FileWrite(CString fileName, BYTE * buff, int wLen)
{
	FILE * pf;
	if((pf=fopen(fileName,"ab"))==NULL)
	{
		MessageBox("打开文件错误");
		return;
	}
	fwrite(buff,sizeof(BYTE),wLen,pf);
	fclose(pf);
}

void CDlgEnc::OnButInpath() 
{
	UpdateData(TRUE);
	ChoseFilePath(m_inPath);
	UpdateData(FALSE);
	
}

void CDlgEnc::OnButKeypath() 
{
	UpdateData(TRUE);
	ChoseFilePath(m_keyPath);
	UpdateData(FALSE);
	
}

void CDlgEnc::OnButOutpath() 
{
	UpdateData(TRUE);
	ChoseFilePath(m_outPath);
	UpdateData(FALSE);
	
}

extern LPSTR m_CmdLine;
BOOL CDlgEnc::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	CString filePath=m_CmdLine;
	if(filePath.GetLength() > 1 )
	{
		filePath.Delete(0);
		this->SetDlgItemText(IDC_EDIT_ENC_INPATH,filePath);
		m_outPath = filePath;
		m_outPath += ".enc";
		this->SetDlgItemText(IDC_EDIT_ENC_OUTPATH,m_outPath);
	}
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

BYTE * CDlgEnc::Base64(int ioflag,BYTE * in,int & length)
{
	BYTE  * out=(BYTE *)malloc(sizeof(BYTE)*length*2);
	if(ioflag==0)
	{
		length=EVP_EncodeBlock(out,in,length);
		return out;
	}
	else if(ioflag==1)
	{
		int pad=0;
		BYTE *p=in+length-1;
		for(int i=0;i<4;i++)
		{
			 if(*p=='=')pad++;
			 p--;
		}
		length=EVP_DecodeBlock(out,in,length);
		length-=pad;
		return out;
	}
	return NULL;
}

DWORD WINAPI SrvThread(PVOID pParam)
{
	CDlgEnc * pDlg = (CDlgEnc *)pParam;

	_encFileStruct * headSt = new _encFileStruct;
	headSt->encTimes=0;
	pDlg->m_outPath.Replace("\\","\\\\");
	pDlg->m_inPath.Replace("\\","\\\\");

	long fLen;
	long fStart=0;
	int endFlag=0;
	int outLen=0;
	int encLeft=MAX_ENCLEN;
	BYTE * buff;
	BYTE * outBuff, * tempBuff;
	CString strtemp="";
	int i=0;
	char temp=pDlg->m_inPath.GetAt(pDlg->m_inPath.GetLength()-1);
	while(temp!='\.')
	{
		strtemp.Insert(0,temp);
		i++;
		temp=pDlg->m_inPath.GetAt(pDlg->m_inPath.GetLength()-i-1);
	}
	strcpy(headSt->fileType,strtemp.GetBuffer(strtemp.GetLength()));

	buff=pDlg->FileRead(pDlg->m_inPath,MAX_ENCLEN,fStart,fLen);
	if(buff==NULL) return 0;
	encLeft=fLen;
	headSt->encTimes = fLen/MAX_ENCLEN +1;//////////
	int * blockSize= (int *)malloc(sizeof(int) * headSt->encTimes);
	pDlg->FileWrite(pDlg->m_outPath,(BYTE *)headSt, sizeof(_encFileStruct)+sizeof(int) * headSt->encTimes );
	i = 0;
	CString info;
	do
	{
		if(encLeft > 0)
		{
			if(encLeft >= MAX_ENCLEN)
			{
				pDlg->InitEnc();
				outBuff = pDlg->Encrypt(buff,MAX_ENCLEN,outLen);
				tempBuff = outBuff;
				pDlg->FileWrite(pDlg->m_outPath,outBuff,outLen);
				fStart+=MAX_ENCLEN;
				encLeft-=MAX_ENCLEN;
				blockSize[i] = outLen;
				i++;///////////////
			//	headSt->encTimes++;
				buff=pDlg->FileRead(pDlg->m_inPath,MAX_ENCLEN,fStart,fLen);

				delete tempBuff;
				info.Format("还剩%d",encLeft);
				pDlg->m_infoList.InsertString(0,info);
			}
			else if(encLeft >= 0)
			{
				pDlg->InitEnc();
				outBuff = pDlg->Encrypt(buff,encLeft,outLen);
				tempBuff = outBuff;
				pDlg->FileWrite(pDlg->m_outPath,outBuff,outLen);
				blockSize[i]=outLen;
				i++;
				endFlag = 1;

				delete tempBuff;
				info.Format("加密完成");
				pDlg->m_infoList.InsertString(0,info);
			}
			else
				endFlag=1;
		}
		else endFlag=1;

	}
	while(endFlag!=1);

	HANDLE  hFile=CreateFile(pDlg->m_outPath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	HANDLE hFilemap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);
	_encFileStruct * pVoid=(_encFileStruct *)MapViewOfFile(hFilemap,FILE_MAP_ALL_ACCESS,0,0,sizeof(_encFileStruct)+sizeof(int)*headSt->encTimes);
	pVoid->encOrder=pDlg->m_encOrder;
	pVoid->keyOrder=pDlg->m_keyOrder;
	pVoid->encTimes=headSt->encTimes;
	pVoid->headSize=sizeof(_encFileStruct);
	for(int j=0;j<10;j++)
		pVoid->fileType[j] = headSt->fileType[j];

	pVoid += 1;
	int * pTemp = (int *)pVoid;
	for(j=0;j<headSt->encTimes;j++)
		pTemp[j] = blockSize[j];

	UnmapViewOfFile(pVoid);
	CloseHandle(hFilemap);
	CloseHandle(hFile);

	return 0;
}

void CDlgEnc::OnButEncGo() 
{
	this->SetEncInfo();
	CreateThread(NULL,0,SrvThread,this,NULL,NULL);
}