信息时代的迅速到来向加密技术提出了甚为迫切的要求。国际互联网络把世界联成一个整体,极大地加大了信息的流通速度,加快了社会生活的步伐。但在互联网的背后还存在着很多的不安全的因素,例如网络通信的安全问题,若不采取一定的措施加以防范,一些重要的、机密的信息就很容易被偷阅、篡改甚至冒名伪造。由此可见解决信息通信安全问题的重要性和紧迫性。
实际上,可采用许多措施解决信息安全问题,例如:防火墙、网络软件加密狗、信息加密技术等,其中,信息加密技术是最直接、最有效的办法。
一、传统的信息加密和破译密码的方法
1、传统的加密方法
(1)代码加密
通信双方预先设定一组代码,加密和解密就是根据这一组代码来完成的。这种方法的缺点是只能传送原来预先约定好的信息,多次使用代码后容易被窃密。
(2)替换加密
明文中的每个字母被替换成另一个字母,该法还不如代码加密。因为,窃密者只要多次搜索一些密文就能够发现其中的规律。
(3)变位加密
将明文的顺序按密钥重新排列。
(4)一次性密码薄加密_
密码薄每一页是不同的代码表,每页只用一次,用其中的代码给明文加密。要破译密文的唯一办法,就是要获得一份相同的密码薄,而这是很困难的。这种方法既保持代码的可靠性,又保持替换加密器的灵活性。但这种方法代价高(同样的密码薄要送到对方),生成一次性密码必须是随机的,否则不可能安全。这种方法一般用于高度保密的场合。
2、破译密码的常用方法
(1)密码穷尽搜索
(2)密码分析
(3) 已知明文的破译方法,例如分析电子邮件信头的固定格式得出密钥。
(4)选定明文的破译法,先加密一段选定的明文再由密文和明文分析密钥。
(5)差别比较法,先加密一组相似却差别细微的明文,然后比较它们的结果,从而获得密钥。
由此可见,各种传统的信息加密方法都有不足之处,就一次性密码薄加密法来说,密钥的分发十分复杂,产生密码薄麻烦、代价高。经过深入研究和探索,我们对传统加密技术中的一次性密码薄加密方法进行了优化改进。这种方法最大的优点是密码薄根据密钥临时随机产生,从而克服以上缺陷,我们把这种方法称为“动态伪随机序列加密法”。
二、动态伪随机序列加密法的原理
设用户密码序列为Ui(i=1,2,…,k),先将用户密码加长(要求大于被加密文件的长度),得到初始加密密钥Ri(i=1,2,…,m),它相当于一次性密码薄加密中的密码薄。为了减少用户密码的重复性,在组成初始加密密钥时选择一定的算法对用户密码进行处理,使密钥Ri序列不具某种规律性,这种算法要求正向运算容易,而反向运算几乎无法实现。改进后的动态伪随机序列加密法具体做法如下:
(1)首先由用户输入密钥(口令),口令长度理论上无上限限制。下面程序人为限制长度的下界长为8个字符,输入的口令先存放在1.DAT中。
(2)1.DAT的内容复制到临时的文件TEMP1DAT中去。
(3)对TEMP1DAT的内容进行两种移位处理,例如输入的口令为“1234567890”则TEMP1DAT移位前用二进制表示见表1。
每个字节的相同位,循环左移n位,n是由密码钥前3字节相同位所组成的数(可以取更多或更少个字节),例表1中第4位n=(111)2=7,则各位左移后(此时左右方向和表格相同)得如下结果:
再对各字节做循环左移m位:m是各字节低三位所组成的数(可以取得更多或更少位),例如第0字节m=(010)2=2,全部左移(字节的低位向高位移位)后得表3:
(4)表移位处理后的TEMP1DAT数据添加到1.DAT的尾部。
(5)若1.DAT的长度大于或等于被加密文件的长度,则密码薄11DAT形成完毕,转(6),否则重复步骤(2)、(3)、(4)、(5)。
(6)用所形成的密码薄对明文加密(或解密),加密时从被加密文件和密码薄文件中各取一个字节进行位异或运算,结果做为密文的内容,解密时再做一次异或运算即可。最后所形成的密码薄中,最前面的若干字节就是原始口令,越靠文件末尾的字节通过运算的次数越多。为了防止被已知明文破译法破译,密码薄从文件尾部向文件头部取数据。因为从文件头开始取数据,头几个原始密码就有可能去加密某个具有固定格式的文件头(如电子邮件、word文档、图象文档的文件头),这样密码就很容易被破译。有了密码就容易产生密码薄,而从文件尾向前取数据,则很难破解。而且原始密码常常最终用不到,因为密码薄的长度为口令长×2i(i=0,1,2……,),大部分情况是超过被加密文件的长度。
由上述步骤可见密码簿的生成不仅与密钥串中多位密码相关,还与加密过程相关,因而各密钥位间存在着很强的相关性。从理论上很容易分析出上述变换是单向的,即只能由用户密码推算出实际加密密钥。不可能由实际密码簿反向推出用户密码。由此产生了一串永不重复且难以推算出后序密码钥的密钥序列流。
三、动态伪随机序列加密法的应用
以上文件加密原理用BC++311编写的程序Jm.c如下:
#include〈process1h〉
#include〈conio1h〉
#include〈io1h〉
#include〈stdio1h〉
#include〈fstream1h〉
#include〈math1h〉
voidmove1()//字节间同位的循环左移
{
FILE3fp;
inthandle,m;
longl,i,j;
charch,ch1;
unsignedsavel[8],m1,m2;
fp=fopen(“temp1dat”,“r+”);
handle=fileno(fp);
l=filelength(handle);
//文件长度for(i=0;i〈8;i++)
{
fseek(fp,i,0);
save1[i]=fgetc(fp);
}
for(j=0;j〈8;j++)
{
m1=pow(2,j);
m2=255-ml;
m=((save1[0]&;m1)〉〉j)+(((save1[1]&;m1)〈〈j)〈〈1)+((save1[2]&;m1)〉〉j)〈〈2);
for(i=0;i〈l;i++)
{
fseek(fp,i,0);
ch=fgetc(fp);
if(i+m〈=l-1)
{
fseek(fp,i+m,0);
ch1=fgetc(fp);
}
elsech1=save1[(i+m)-l];
ch1=ch1&;m1;
ch=(ch&;m2)_ch1;
fseek(fp,i,0);
fputc(ch,fp);
}
}
fclose(fp);}
voidmove2()_//字节内循环左移
{
FILE3fp;
inthandle;
longl,i;
intj;
charch,ch1,ch2;
fp=fopen(“temp1dat”,“r+”);
handle=fileno(fp);
l=filelength(handle);
for=(i=0;i〈1;i++)
{
fseek(fp,i,0);
ch=fgetc(fp);
j=ch&;7;
ch1=ch〈〈j;
ch2=ch〉〉(8-j);
ch=ch1+ch2;
fseek(fp,i,0);
fputc(ch,fp);
}
fclose(fp);
}
longhb()__//把temp1dat接到1.dat尾部{
long1;
inthandle;
charch;
ifstreaminfile;
ofstreamoutfile;
outfile1open(“11dat”,ios∷app_ios∷binary);
infile1open(“temp1dat”,ios∷in_ios∷binary);
while(outfile&;&;infile1get(ch)&;&;(ch!=0xd)&;&;(ch!=0xa))outfile1put(ch);
infile1close();
outfile1close();
FILE3fp1;
fp1=fopen(“11dat”,“r+”);
handle=fileno(fp1);
1=filelength(handle);
fclose(fp1);
returnl;__//返回合并后文件的长度
}
voidmycopy()__//复制文件
{
charch;
ifstreaminfile;
ofstreamoutfile;
infile1open(“l1dat”,ios∷in_ios∷binary);
outfile1open(“temp1dat”,ios∷out_ios∷binary);
while(outfile&;&;infile1get(ch))outfile1put(ch);
infile1close();
outfile1close();
}
voidjm(FILE3fp1)//用所形成的密码簿加密文件
{
FILE3fp2;
inthandlel;
longl1,i;
charch1,ch2;
fp2=fopen(“11dat”,“rb”);
handle1=fileno(fp1);
l1=filelength(handle1);
for(i=0;i〈11;i++)
{
fseek(fp1,i,0);
chl=fgetc(fp1);
fseek(fp2,-i-1,2);
ch2=fgetc(fp2);
chl=(ch1ch2);
fseek(fp1,i,0);
fputc(ch1,fp1)
}
fclose(fp2);
}
intinpassword()__//输入密钥并把原始密钥存入文件l1dat中
{
inti=0;
charch;
ofstreamoutfile;
outfile1open(“l1dat”,ios∷out|ios∷binary);
cout〈〈“inputpassword:”;
ch=getch();
while((ch!=0xd)&;&;(ch!=0xa))__//按回车结束口令输入
{
outfile〈〈ch;
cout〈〈“3”;
ch=getch();
i++;
}
outfile1close();
if(i〈8)return1;
elsereturn0;
}
voidmain(intargc,char3argv[])//主函数
{
FILE3fpl;
Char3fname;
fp1=fopen(argv[1]1“rb+”);
inthandle;
longl1,l2=0;
handle=fileno(fp1);
l1=filelength(handle);
if(inpassword())
cout〈〈endl;
(〈“Passwordistooshort!〉=8)”〈〈endl;
else
{
while(11>;12)
{
mycopy();
move1();
move2();
12=hb();
}
jm(fp1);
}
fclose(fp1);
//关闭文件、删除临时文件fname=“l1dat”;
unlink(fname);
fname=“temp1dat”;
unlink(fname);
}
该程序的使用方法:在操作系统下直接输入命令:
Jm〈被加密文件名〉
(含扩展名)InputPassword:
********(在此输入8个字符以上的口令并回车)
加密和解密执行方法相同,执行以上程序奇数次是加密,偶数次是解密。亦可使用本程序用不同的密码多次加密,若用多个密码多次加密各组密码使用的顺序没有限制,由于有这个优点,可将极重要的密码分别交给几个人保管,要想解开密码必须要几个人同时在场方可实现,这种加解密码方式对于银行资金汇划和清算等方面的管理或是公安、国防等方面机密文件的传送极为有用,特别是计算机网络中,一些重要数据禁止非法用户使用,使用这种加密方式可以确保数据和文件的安全。
小知识之银行资金汇划
简单的说就是联行资金往来,即跨行资金的汇入汇出,既包括系统内营业机构之间的资金往来,也包括系统外资金往来。主要业务有:汇兑、委托收款(划回)、托收承付(划回)、同业拆借、系统内资金调拨等,以及引伸来的通存通兑、系统内他行代记账等等。