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

📄 safedatasetpage.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//加载硬盘里面的.evp文件,读取文件信息,并写入MAP,然后显示在列表中
BOOL CSafeDataSetPage::ParseEvp(CString strEvpFile, EncType & encType)
{
	m_uIndex = 0; //添加目录时候不清0,因为可能多次添加

	CFile File;
	if(!File.Open(strEvpFile, CFile::modeRead | CFile::typeBinary))
	{
		AfxMessageBox(MiniCT_1320);
		return FALSE;
	}
	//读取文件前5个字母,判断是否为Evp20
	char sHeadMark[6] = {0};
	File.Read(sHeadMark, strlen(m_sHeadMark));
	if(strcmp(sHeadMark, m_sHeadMark)!=0)
	{
		//非EVP文件,返回
		File.Close();
		AfxMessageBox(MiniCT_1305);
		return FALSE;
	}
	DWORD dFileInfoLen = 0; 
	File.Read(&dFileInfoLen, sizeof(DWORD));
	//校验CRC,类型UINT
	UINT uCrcCheck = 0;
	File.Read(&uCrcCheck, sizeof(UINT));
	if(!CRC::CheckCrc((char *)&dFileInfoLen, sizeof(DWORD), uCrcCheck))
	{
		AfxMessageBox(MiniCT_1306);
		File.Close();
		return FALSE;
	}

	//开辟缓冲区,容纳加密后的信息体
	BYTE * pIn = new BYTE[dFileInfoLen + 1];
	File.Read(pIn, dFileInfoLen);

	HRSRC hRsrc = FindResource(NULL,MAKEINTRESOURCE(IDR_FILE_KEY),"CERT");
	DWORD lenKey = SizeofResource(NULL, hRsrc); 
	HGLOBAL hgKey = LoadResource(NULL,hRsrc);
	LPSTR lpKey = (LPSTR)LockResource(hgKey);

	DWORD dOutLen = dFileInfoLen;

	//开辟缓冲区,容纳解密后的信息体
	BYTE * pOut = new BYTE[dOutLen];

	CString outMsg;


	if(!CEvp::RSAPrivDec((BYTE *)lpKey, lenKey, "MiniCA", pIn, 
		dFileInfoLen, pOut, dOutLen, outMsg.GetBuffer(256)))
	{
		//解密失败
		AfxMessageBox(MiniCT_1307);
		File.Close();
		delete [] pIn;
		delete [] pOut;
		return FALSE;
	}

	CMemFile MemFile;
	MemFile.Attach(pOut, dOutLen);

	//首先是加密方式
	MemFile.Read(&encType, sizeof(EncType));
	m_EncType = encType;

	//然后是结构体个数
	UINT uIndex = 0;
	MemFile.Read(&uIndex, sizeof(uIndex));

	CSuperGridCtrl::CTreeItem * pItem[1024];	//只记录文件夹
	memset(pItem, 0, sizeof(CSuperGridCtrl::CTreeItem * ) * 1024);
	
	CMap<UINT, UINT, CSuperGridCtrl::CTreeItem *, CSuperGridCtrl::CTreeItem * > ItemMap;//记录目录ITEM的MAP
	ItemMap.SetAt(0, NULL);

	SHFILEINFO sfi = {0};


	//最后是n个结构体
	for(UINT index = 1, j = 1; index <= uIndex; index++, m_uIndex++)	//读取文件信息到结构MAP
	{
		CDataSafe DataSafe;
		DataSafe.Read(MemFile);
		
		CSuperGridCtrl::CTreeItem * pParentItem = NULL;
		if(ItemMap.Lookup(DataSafe.uParentID, pParentItem))
		{
			
			SYSTEMTIME stime;
			FILETIME ftime; 
			FileTimeToLocalFileTime(&DataSafe.ftLastWriteTime, &ftime); // 转换成本地时间 
			FileTimeToSystemTime(&ftime, &stime); // 转换成系统时间格式
			
			//时间
			CString strTime;
			strTime.Format("%d-%d-%d %d:%d", stime.wYear, stime.wMonth, stime.wDay, stime.wHour, stime.wMinute);
			
			if(!DataSafe.bIsFile)//目录,记录下来
			{
				
				SHGetFileInfo (NULL, FILE_ATTRIBUTE_DIRECTORY, &sfi, sizeof(SHFILEINFO),
					SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
				
				pItem[j] = AddDataSet(&DataSafe, DataSafe.cName, sfi.iIcon, 
					DataSafe.dOldLen, 0, sfi.szTypeName, strTime, pParentItem);
				ItemMap.SetAt(j, pItem[j]);
				j++;
			}
			else
			{
				SHGetFileInfo(DataSafe.cName, FILE_ATTRIBUTE_NORMAL, &sfi,
					sizeof(SHFILEINFO), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX| SHGFI_TYPENAME );
				
				AddDataSet(&DataSafe, DataSafe.cName, sfi.iIcon, DataSafe.dOldLen, DataSafe.dNewLen,
					sfi.szTypeName, strTime, pParentItem);
			}
		}
		
	}

	delete [] pIn;
	delete [] pOut;

	MemFile.Close();
	File.Close();


/*	for(int index = 1, j = 0; index <= m_DataMap.GetCount(); index++, m_uIndex++)
	{
	}*/
	//如果分析成功,则转换为解密方式,需要完成,按钮等的变化
//	SetDlgItemText(IDC_B_ENC, "解密");
	m_BEnc.SetIcon(IDI_ICON_DDEC);

	((CButton *)GetDlgItem(IDC_RADIO1))->SetCheck(0);
	((CButton *)GetDlgItem(IDC_RADIO2))->SetCheck(0);
	((CButton *)GetDlgItem(IDC_RADIO3))->SetCheck(0);
	((CButton *)GetDlgItem(IDC_RADIO4))->SetCheck(0);
	((CButton *)GetDlgItem(IDC_RADIO5))->SetCheck(0);
	((CButton *)GetDlgItem(IDC_RADIO6))->SetCheck(0);

	GetDlgItem(IDC_RADIO1)->EnableWindow(0);
	GetDlgItem(IDC_RADIO2)->EnableWindow(0);
	GetDlgItem(IDC_RADIO3)->EnableWindow(0);
	GetDlgItem(IDC_RADIO4)->EnableWindow(0);
	GetDlgItem(IDC_RADIO5)->EnableWindow(0);
	GetDlgItem(IDC_RADIO6)->EnableWindow(0);

	switch(m_EncType)
	{
	case NONE:
		break;
	case CRYPT:	//对称 1
		OnRadio1();
		GetDlgItem(IDC_RADIO1)->EnableWindow(1);
		((CButton *)GetDlgItem(IDC_RADIO1))->SetCheck(1);
		break;
	case DIGEST:	//摘要 3
		OnRadio3();
		GetDlgItem(IDC_RADIO3)->EnableWindow(1);
		((CButton *)GetDlgItem(IDC_RADIO3))->SetCheck(1);
		break;
	case SIGN:		//签名 4
		OnRadio3();
		GetDlgItem(IDC_RADIO4)->EnableWindow(1);
		((CButton *)GetDlgItem(IDC_RADIO4))->SetCheck(1);
		break;
	case SEAL:	//信封 2
		OnRadio4();
		GetDlgItem(IDC_RADIO2)->EnableWindow(1);
		((CButton *)GetDlgItem(IDC_RADIO2))->SetCheck(1);
		break;
	case PubEnc:
		OnRadio5();
		GetDlgItem(IDC_RADIO5)->EnableWindow(1);
		((CButton *)GetDlgItem(IDC_RADIO5))->SetCheck(1);
		break;
	case PrivEnc:
		OnRadio6();
		GetDlgItem(IDC_RADIO6)->EnableWindow(1);
		((CButton *)GetDlgItem(IDC_RADIO6))->SetCheck(1);
		break;
	default:
		break;
	}	
	m_bIsEnc = FALSE;
	m_strEvpPath = strEvpFile;	//設置解密文件
	return TRUE;
}

CProgressCtrlST * CSafeDataSetPage::ShowProg(int nItem, int nCol)
{
//	CString strFind = GetItemText(nItem, nCol);

	//basic code start
	CRect rect;
	int offset = 0;
	// Make sure that the item is visible
	if( !m_DataSetList.EnsureVisible(nItem, TRUE)) return NULL;
	m_DataSetList.GetSubItemRect(nItem, nCol, LVIR_BOUNDS, rect);
	// Now scroll if we need to expose the column
	CRect rcClient;
	m_DataSetList.GetClientRect(rcClient);
	if( offset + rect.left < 0 || offset + rect.left > rcClient.right )
	{
		CSize size;
		size.cx = offset + rect.left;
		size.cy = 0;
		m_DataSetList.Scroll(size);
		rect.left -= size.cx;
	}
	
	rect.left += offset;	
	rect.right = rect.left + m_DataSetList.GetColumnWidth(nCol);
	if(rect.right > rcClient.right) 
	   rect.right = rcClient.right;
	//basic code end

	rect.bottom += rect.Height();//dropdown area
	
	DWORD dwStyle =  WS_CHILD | WS_VISIBLE;
	CProgressCtrlST *pProg = new CProgressCtrlST;
	pProg->Create(dwStyle, rect, this, 100050);
	pProg->SetBitmap(IDB_BITMAP_PROG);
	pProg->SetPos(40);
//	pList->ModifyStyleEx(0,WS_EX_CLIENTEDGE);//can we tell at all
//	pList->SetHorizontalExtent(CalcHorzExtent(pList, lstItems));
//	pList->ShowDropDown();
//	pList->SelectString(-1, strFind.GetBuffer(1));
	// The returned pointer should not be saved
	return pProg;
}


//功能:
		//写入 版本Evp20, 加密结构长度, 加密结构校验
		//移动文件到加密位置(掠过信息颈)
//参数:
		//File - 用来加密文件的
		//nCount - 文件信息体个数
		//dFileInfoLen - 返回加密后长度
		//strMsg - 返回操作错误信息
BOOL CSafeDataSetPage::MadeFileHead(CFile & File, const int nCount, DWORD & dFileInfoLen, CString & strMsg)
{
	if(0 == nCount)
	{
		strMsg = MiniCT_1308;
		return FALSE;
	}
	
	HRSRC hRsrc = FindResource(NULL,MAKEINTRESOURCE(IDR_FILE_CERT),"CERT");
	DWORD lenCert = SizeofResource(NULL, hRsrc); 
	HGLOBAL hgCert = LoadResource(NULL,hRsrc);
	LPSTR lpCert = (LPSTR)LockResource(hgCert);
	
	
	//取得加密后文件信息体大小
	//文件信息体为: 加密方式sizeof(EncType) +  sizeof(int)(信息体个数 int 类型) + n个CDataSafe结构大小nCount * (sizeof(CDataSafe) - sizeof(char)*256
	//其中CDataSafe结构不写入文件全路径,所以 - sizeof(char)*256
	//
	dFileInfoLen = CEvp::GetEncLen(lpCert, lenCert, 
		sizeof(EncType) + sizeof(nCount) + nCount * (sizeof(CDataSafe) - sizeof(char)*256) );
	if(dFileInfoLen == -1)
	{
		strMsg = MiniCT_1309;
		return FALSE;
	}

	//写入版本标志Evp20
	File.Write(m_sHeadMark, strlen(m_sHeadMark));
	//写入加密后文件信息体大小,类型为DWORD
	File.Write(&dFileInfoLen, sizeof(DWORD));
	//写入CRC校验值,类型UINT
	UINT uCrcCheck = 0;
	if(CRC::GetCrc16((char *)&dFileInfoLen, sizeof(DWORD), uCrcCheck))
	{
		File.Write(&uCrcCheck, sizeof(UINT));
	}
	else
	{
		strMsg = MiniCT_1310;	//"生成信息颈长度CRC校验失败";
		AddMsg(strMsg, M_ERROR);
		return FALSE;
	}
	
	//预留信息头 
	File.Seek(dFileInfoLen, CFile::current);
	return TRUE;
}

//功能:	- 加密文件完毕后调用
		//写入 加密(加密方式+文件个数+文件信息体加密后长度)后内容
		//移动文件到加密位置
//参数:
		//File - 用来加密文件的
		//encType - 加密方式
		//nCount - 文件信息体个数
		//dFileInfoLen - 加密后长度,用于分配内存
		//strMsg - 返回操作错误信息

BOOL CSafeDataSetPage::MadeFileNeck(CList<CDataSafe *, CDataSafe *> * pDataList, CFile &File, 
									const EncType encType, const int nCount, 
									const DWORD dFileInfoLen, CString &strMsg)
{
	//开始屏蔽进度显示 , 完毕后打开
	CSafeDataSetPage::m_pProgOne = NULL;

	//构造内存文件,写入 加密方式 + 信息体个数n + n个信息体
	CMemFile MemFile;

	MemFile.Write(&encType, sizeof(EncType));

	MemFile.Write(&nCount, sizeof(int));

	//枚举目录列表
	POSITION pos = pDataList->GetHeadPosition();
	while(pos != NULL)
	{
		CDataSafe* pDataSafe = pDataList->GetNext(pos);
		if(pDataSafe)
			pDataSafe->Write(MemFile);
	}
	//加密内存文件
	//构造加密结果 长度+1 内存
	DWORD dOutLen = -1;
	BYTE * pOut = new BYTE[dFileInfoLen + 1];
	dOutLen = dFileInfoLen;

	HRSRC hRsrc = FindResource(NULL,MAKEINTRESOURCE(IDR_FILE_CERT),"CERT");
	DWORD lenCert = SizeofResource(NULL, hRsrc); 
	HGLOBAL hgCert = LoadResource(NULL,hRsrc);
	LPSTR lpCert = (LPSTR)LockResource(hgCert);

	//构造加密输入
	DWORD dInLen = MemFile.GetLength();
	BYTE * pIn = MemFile.Detach();	//同时关闭MemFile.Close(); 此时不要重新开辟内存,而且Detach用malloc,所以释放用free
	

	if(!CEvp::RSAPubEnc((BYTE *)lpCert, lenCert, "", pIn, dInLen, 
		pOut, dOutLen, strMsg.GetBuffer(256)))
	{
		//加密失败
		strMsg.ReleaseBuffer();
		free(pIn);
		delete [] pOut;
		CSafeDataSetPage::m_pProgOne = &m_ProgOne;
		return FALSE;
	}
	else if(dOutLen != dFileInfoLen)
	{
		//加密失败
		strMsg.ReleaseBuffer();
		strMsg = MiniCT_1311;//"信息颈长度与预期不符";
		free(pIn);
		delete [] pOut;
		CSafeDataSetPage::m_pProgOne = &m_ProgOne;
		return FALSE;
	}

	CSafeDataSetPage::m_pProgOne = &m_ProgOne;
	
	//移动文件指针到开头 + "Evp20" + 加密后信息体大小DWORD + CRC校验UINT
	File.Seek(strlen(m_sHeadMark) + sizeof(DWORD) + sizeof(UINT), CFile::begin);
	File.Write(pOut, dFileInfoLen);
	free(pIn);

	delete [] pOut;
	return TRUE;
}

/////////////////////////////////////////////////////加密文件部分////////////////////////////////////////////////
//功能:对称加密文件、目录
//参数:
//		strCpName - 算法名称
//		strPwd- 对称密钥
//		strFileName - 加密后文件
//		outMsg - 返回操作信息
BOOL CSafeDataSetPage::Crypt(CString strCpName, CString strPwd, CString strFileName, CString & outMsg)
{
	//输入检查
	if(strCpName.IsEmpty() || strPwd.IsEmpty() || strFileName.IsEmpty())
	{
		outMsg = MiniCT_1312; //"算法名称或对称密钥或输出文件非法";
		return FALSE;
	}

	CFile File;//文件头加版本信息
	if(!File.Open(strFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary ))
	{
		outMsg.Format("%s : %s", MiniCT_1313,strFileName);	//创建文件失败
		return FALSE;
	}

	int nCount = m_DataSetList.GetCount();

	DWORD dFileInfoLen = 0;

	//创建信息头
	if(!MadeFileHead(File, nCount, dFileInfoLen, outMsg))
	{
		File.Close();
		return FALSE;
	}

	DWORD dOutLen = -1;

	EVP_CIPHER_CTX Ctx, CtxTemp;
	if(!CEvp::InitCrypt2(strCpName, strPwd, 1, Ctx))
	{
		outMsg = MiniCT_1314; //"初始化加密结构失败";
		File.Close();
		return FALSE;
	}

	//枚举目录列表加密信息
	CList<CDataSafe *, CDataSafe *> DataList;	//包含目录和文件得全部信息列表

	EnumList(&DataList);
	POSITION pos = DataList.GetHeadPosition();
	int iCount = DataList.GetCount();
	m_ProgAll.SetRange(0, iCount);
	int iFinish = 0;

	CString strInfo;

	while(pos != NULL)
	{
		CDataSafe* pDataSafe = DataList.GetNext(pos);
		if(pDataSafe)
		{
			if(pDataSafe->bIsFile) //文件则加密
			{
				strInfo.Format("%s %s ,%s %d %s", MiniCT_1315, pDataSafe->cName, MiniCT_1316, pDataSafe->dOldLen, MiniCT_1317);
				AddOnceMsg(strInfo);
				CtxTemp = Ctx;
				//结构中加密起始位置赋值
				pDataSafe->dBeginSeek = File.GetPosition();
				dOutLen = CEvp::Crypt2(&CtxTemp, pDataSafe->cPathName, File, 0, outMsg);
				if(dOutLen == -1)
				{
					CString str;
					str.Format("%s%s, %s%s", pDataSafe->cName, MiniCT_1318, MiniCT_1319, outMsg);//对称加密失败 失败原因:
					outMsg = str;
					File.Close();
					CleanList(&DataList);
					return FALSE;
				}
				else//结构赋值
				{
					pDataSafe->dNewLen = dOutLen;
				}
			}
		}
	
		m_ProgAll.SetPos(++iFinish);
	}

	//创建信息颈
	if(!MadeFileNeck(&DataList, File, CRYPT, nCount, dFileInfoLen, outMsg))
	{
		File.Close();
		CEvp::CleanCrypt2(Ctx);
		CleanList(&DataList);
		return FALSE;
	}

	CEvp::CleanCrypt2(Ctx);
	CleanList(&DataList);

	File.Close();
	return TRUE;
}

//对称解密
BOOL CSafeDataSetPage::DecCrypt(CString strCpName, CString strPwd, CString strEvpFile, CString & outMsg)
{
	//解密信息
	DWORD dOutLen = -1;

⌨️ 快捷键说明

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