我前幾天在VC知識庫(VCKBASE.COM)下載了一個 "徐景周" 做的一個叫<加密之星>的小工具的源代碼,我把它編譯後拿文件來實驗一下發現它對大多數文件都不管用.比如,加密文本文件只有文件的前一部分被加密而大部分還完整的存在, 如果用來加密mp3,簡直就不起作用,加密後的mp3還是能很好的從頭播放的尾..所以我自己發明了一種文件加密的方法,雖然很簡單,但是能安全地加密任何計算機上的文件而且還可以用同一密碼對同一文件進行多次加密。
我用的方法是把文件從頭到尾的每一個字節都讀出來然後加密,具體做法如下:(請參照源代碼);
新建一個基於對話框的工程(起名為ecflie,然後去掉確定、取消、和系統添加的靜態控件.在對話框添加三個按鈕和兩個編輯控件.給兩個編輯控件分別關聯變量CString m_path和CString m_pass,其中m_pass作為用戶輸入的密碼,m_path作為文件路徑;
其中三個按鈕分別為浏覽、加密、解密按鈕.
添加以下函數:
__int64 epass(); //密碼初始化函數
BOOL ecfile(LPCTSTR fpath);//文件加密函數
BOOL dcfile(LPCTSTR fpath);//文件解密函數
//給文件加密的函數BOOL CEcfileDlg::ecfile(LPCTSTR fpath)
{
char *data;
CFile *file;
DWORD flen;
m_password = epass();//密碼初始化
file = new CFile;
if ( !file->Open(fpath, CFile::shareDenyNone|CFile::modeReadWrite))
{
return FALSE;
}
flen = file->GetLength();
data = new char[(int)flen];//為文件分配內存
file->SeekToBegin();
file->Read(data, flen);
//這裡把文件的所有字節都進行加密了
for(int i=0; i<(int)flen; i++)
{
data[i] ^= m_password;
data[i] ^= flen; //因為每次加密後文件的大小都會增加5字節,所以如果兩次用同一密碼進行加密也沒關系
}
file->SeekToBegin();
file->Write(data, flen);
delete[] data; //先釋放內存
//添加密碼驗證信息
char cpass[5] = "love";
for(int j=0; j<5; j++)
{
cpass[j] ^= m_password;
}
file->SeekToEnd();
file->Write(&cpass, 5); //在文件尾添加密碼嚴整部分,,這樣文件就會增加5字節
file->Close();
delete file;
return TRUE;
}
//給文件解密的函數BOOL CEcfileDlg::dcfile(LPCTSTR fpath)
{
char *data;
CFile *file;
DWORD flen;
char love[5];
file = new CFile;
if( !file->Open(fpath, CFile::shareDenyNone|CFile::modeReadWrite))
{
return FALSE;
}
flen = file->GetLength();
data = new char[(int)flen];
//檢驗密碼是不是正確
file->Seek(-5, CFile::end);
file->Read(&love, 5);
m_password = epass();
for(int i=0; i<5; i++)
{
love[i] ^= m_password;
}
if(strcmp(love, "love")!=0)
{
return FALSE;
}
//解密
file->SeekToBegin();
file->Read(data, flen);
//按照原來的方法進行解密
for(int j=0; j<(int)flen; j++)
{
data[j] ^= m_password;
data[j] ^= (flen-5);
}
file->SeekToBegin();
file->Write(data, flen);
file->SetLength(flen-5); //刪除加密是添加的密碼驗證部分
file->Close();
delete[] data;
delete file;
return TRUE;
}
上面取得密碼的函數(m_password = epass();)可以自己定義,我只把密碼進行簡單的運算:__int64 CEcfileDlg::epass()
{
DWORD plen;
char *ppass;
__int64 mc= 8757735233305;
UpdateData(TRUE);
ppass = m_pass.GetBuffer(0);
plen = strlen(ppass);
for(int i=0; i<(int)plen; i++)
{
mc ^= ppass[i]|128;
}
return mc;
}
然後在適當的地方調用這兩個函數就可以了. 具體細節請查看源代碼,(在WIN XP下調試通過了)。
本文配套源碼