📄 safedatasetpage.cpp
字号:
//加载硬盘里面的.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 + -