摘 要 针对当前密码破解软件的大量出现,文件数据的安全性受到一定的威胁,如Office系列文件、数据库文件、WinRAR等文件的密码形同虚设,毫无机密而言。由于传统数据加密模式始终带有一定的静态性即同一个文件无论什么时候加密其结果始终相同,这样就为破解者提供了破解参照,因而存在着一定的安全隐患。为此,在这里提出一种动态位算法加密技术实现的全新思路及其实现方法。
关键词 VC++,动态位算法,加密技术
一、 现方法
先介绍一下位算法加密方法的基本原理即按算法对数据进行位取反时产生出加密数据,当再次按相同的算法对数据进行位取反时则还原,由此说明产生加密数据的核心是位加密算式,同时还要求加密式与解密式必须完全相同才能加密还原。既然算式是产生加密数据的核心,那么如何让算式动起来呢,关键是利用系统时间与系统运行时间的动态性来实现,基本思路是首先提取系统时间与运行时间作为加密算式的动态参数进行文件加密;然后将有关动态参数动态加密后追加在加密文件中,否则无法解密文件;最后解读出追加的有关参数对文件进行解密。这样随着算式中时间参数的不断变化即便是同一个文件在不同时间加密出来的数据也完全不同,这样让破解者找不到破解参照,当然也就无从下手破解。
二、应用实例
在VC++6.0中创建一个名为DynamicLock的对话框程序并添加三个按钮,其中一个按钮用于浏览文件、一个用于加密、另一个用于解密;然后添加两个EditBox文本框,分别用来显示打开的文件与密码输入(如图1);最后添加两个StaticText静态文件,控件分别提示输入密码与处理状态。具体布局如下 准备工作,先依次为以下列控件添加类型变量:
(1)EditBox:显示文本框添置CString类型变量m_filenam。
(2)StaticText:静态显示文本属性中设置“输入密码”。
(3)EditBox:密码框添置CString类型变量m_pass。
(4)StaticText:状态显示框添加CString类型变量m_statu。
然后在对话框类中添加四个函数来分别实现完成有关的功能。
加密函数void类型LockData(char *FileName, char *TempFile, CString strPassWord)
///主用于文件加密。第一个参数为打开文件名;第二个参数临时文件名;第三个输入密码
解密函数void类型 UnLockData( char *FileName, char *TempFile )
///主用于文件解密。其中第一个参数为打开文件名;第二个参数为临时文件名
解读密码函数CString类型GetFilePassWord(char *FileName)
///主用于解读加密文件中所保存的密码。其中参数为打开文件名
加密判断函数BOOL类型GetFileFlag(char *FileName)
///主用于判断打开文件属于加密型还是未加密型。其中参数为打开文件名
最后打开对话框类实现文件源文件DynamicLockDlg.cpp并在其中按以下步骤完成代码的添置。
1.参数赋值
进入对话框类实现文件源文件cpp的开头部位中添加两个全局变量,主要在打开文件时获得初始值,在调用加密或解密函数对其参数进行赋值,具体如下:
char filename[MAX_PATH]; // 包含路径的原文件名
char tempname[MAX_PATH]; //当前路径的临时文件名
CString strPass=""; //追加在文件中的标准密码
2.加密函数所完成的主要功能
(1) 提取系统时间与运行时间作为动态位加密算式的动态参数且均处理成10个字符,便于追加数据时长度固定。
(2) 利用系统运行时间的动态性构成动态位加密算式,对文件进行加密并保存在临时文件中。
(3) 依次将加密判断标志共125个字符加密后追加在临时文件尾,系统运行时间以10个字符形式加密后紧随其后,系统时间以10个字符形式位加密后再随其后,密码以32个字符形式进行并以系统时间与运行时间为动态参数加密追加在最后。
(4) 最后将临时文件中的数据更新到原文件中,再将临时文件数据清空后删除,不留下任何处理痕迹。
void CDynamicLockDlg::LockData(char *FileName, char *TempFile, CString strPassWord)
{
//依次获得系统的时间与启动时间参数来作为构成动态算法公式动态参数
//将系统时间组合成的数处理成10个固定的字符形式以利于追加后便于读取
SYSTEMTIME SysTime; GetSystemTime(&SysTime);
CString strSysTime;
strSysTime.Format("%d%d%d%d",SysTime.wHour,
SysTime.wSecond,SysTime.wMinute, SysTime.wMilliseconds);
unsigned long systime=atol(strSysTime); //追加数据时对运行时间与密码动态加密
strSysTime.Format("%10d", systime); //Afx MessageBox(strSysTime); 检测提取的系统时间
//提取系统运行时间并处理成10个固定的字符形式便于追加长度固定
unsigned long runtime=GetTickCount(); //构成动态算式最关键的动态参数
CString strRunTime; strRunTime.Format("%10u", GetTickCount());
// Afx MessageBox(strRunTime); 检测所提取的系统运行时间
//利用系统运行时间的不重复性作为文件数据加密的动态参数并保存临时文件中
FILE *fp,*ftemp; char cData; //定义文件型指针变量与字符变量
if((fp=fopen(FileName, "rb"))==NULL)
{ MessageBox("打开文件失败!", "提示", MB_OK); return; }
fseek(fp, 0L, SEEK_END); int LenSize=ftell(fp); ///获取文件长度
rewind(fp); ///将指针从新指向文件的开头以便加密文件数据
ftemp=fopen( TempFile, "wb+" ); //以二进制改写方式将加密在临时文件中
int i=0;
while(i!=LenSize)
{ cData=fgetc(fp); //从原文件中读取相应位置的数据
cData^=0xab+(i+2008)%2008+i-runtime; //按动态位加密算法进行动态加密
putc( cData, ftemp ); //将加密后的数据写入临时文件中
i++;
} fclose(fp); fclose(ftemp);
//数据追加,将加密判断标志与有关动态参数加密后最加在文件尾,提供解密时读取
char *data; char c; int ii=0;
ftemp=fopen(TempFile, "ab+"); //以二进制追加的方式打开文件
CString strFlag="The data of file had been locked OK.";
strFlag=strFlag+"The Data Of File Had Been Locked OK.";
strFlag=strFlag+"THE DATA OF FILE HAD BEEN LOCKED OK.";
//首先追加的是123个字符的加密的判断标志,打开文件时据此判断是否加密
data=new char[123]; strcpy(data, strFlag);
for(ii=0; ii<123; ii++ )
{ c=data[ii];
c^=0xab+(ii+123)%123; //以变化的iFlag来体现位加密的动态性
fputc(c, ftemp); ////////////////将判断标志进行动态位加密后追加在后
}
//然后追加的是10个字符的运行时间参数,这是解密文件与密码时的动态参数
data=new char[10]; strcpy(data, strRunTime);
for(ii=0; ii<10; ii++ )
{//利用变化的iRun与运行时间变量共同构成位加密算式的动态性
c=data[ii];
c^=0xab+ii+(ii+2008)%2008+systime%2008;
fputc(c, ftemp);
}
//接着追加的是10个字符的系统时间参数,在解密运行时间与密码时运用
data=new char[10]; strcpy(data, strSysTime);
for(ii=0; ii<10; ii++)
{ c=data[ii];
c^=0xab+ii%5;
fputc(c, ftemp);
}
//最后追加的是32个字符的密码数据
data=new char[32]; strcpy( data, strPassWord );
for(ii=0; ii<32; ii++)
{ c=data[ii];
c^=0xab+(ii+systime)%2008+runtime;
fputc(c, ftemp);
} fclose(ftemp); //追加完毕后将文件关闭
//说明在解密文件或解读追加数据时一定要注意:总共追加了175个字符
//其中依次判断标志123个字符定位在-175L、运行时间10个字符定位在-52L、
//系统时间10个字符定位在-42L、密码32个字符定位在-32L。
//将加密后的临时文件数据更新到原文件中并将临时文件内容清空
CopyFile(TempFile, FileName, 0); //将临时文件中的数据更新到原文件中
ftemp=fopen( TempFile, "wb+" ); //清空临时文件数据,防止留下处理痕迹
fwrite( NULL, 0, 0, ftemp ); fclose(ftemp);
remove(TempFile); /////////////////删除临时文件
}
|