Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15114225
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类: Mysql/postgreSQL

2008-04-01 19:34:36

本文将绍了一个简单易用的加密/解密算法:使用异或(XOR)运算。本算法原理简单,旨在使读者对信息的加密/解密有一个更加直观的印象。 `%SV?)E]  
l7}dw 
  XOR算法原理 hc;8z;De  
`15Wlz4mt  
  从加密的主要方法看,换位法过于简单,特别是对于数据量少的情况很容易由密文猜出明文,而替换法不失为一种行之有效的简易算法。 JPbM&W0f  
 [\NPG  
  从各种替换法运算的特点看,异或运算最适合用于简易加解密运算,这种方法的原理是:当一个数A和另一个数B进行异或运算会生成另一个数C,如果再将C和B进行异或运算则C又会还原为A。 feK`d %#^  
qBrCsMMf=  
  相对于其他的简易加密算法,XOR算法的优点如下。 $!?  $Ulm  
V\8LO$&  
  (1)算法简单,对于高级语言很容易能实现。 >NTi/^T:  
\:wVqEc}Iw  
  (2)速度快,可以在任何时候、任何地方使用。 [(!X # $  
Kpm(9;9  
  (3)对任何字符都是有效的,不像有些简易加密算法,只对西文字符有效,对中文加密后再解密无法还原为原来的字符。 A|A !?H  
4g#h|3s5  
  XOR算法实现 U ^)Mk%a  
Od G|xU  
  上一部分介绍了如何使用XOR运算进行加密/解密的原理,本节将使用其加密用户的登录信息。根据上一小节介绍的XOR加密算法的原理,不难写出以下的加密解密函数。首先列出加密算法。 4m,[r42  
4Mv2856{  
1 <!--encrypy_xor:简单使用XOR运算的加密函数-----------------------> =,+z7#,5 _  
2 <?php U[3Xuk/  
3 //加密函数 6r 
4 function myEncrypt($string, $key) c XESC,Iz  
5 { |^9BO>u  
6 for($i=0; $i<STRLEN($STRING); p $i )<> MO}ZSu^2y  
7 { v"pjBu  
8 for($j=0; $j<STRLEN($KEY); p $j )<> d~10e1"9  
9 { PEv,+:egY  
10 $string[$i] = $string[$i]^$key[$j]; `j[t=/3  
11 } Hh"ccIZ/]  
12 } .6mSV47@  
13 return $string; X.{)*`aq  
14 } p C__]q  
P:a8uKUX  
  第4行定义了加密函数myEncrypt(),输入参数$string为明文,而$key为密钥;输出为使用$key作为密钥并使用XOR加密算法产生的密文。 IGMu,NF  
\%j _4mD  
  第6~12行的外层for循环对明文字符串的每一个字符进行循环,而内层的for循环(第8~11行)对明文的每一字符循环与密钥的每一位做异或运算。其原理已经在上一小节中介绍,不再重述。 C./,\+sE[  
&[k_R/+E  
  同样,与加密函数类似,可以写出下面的解密函数。 7nh/i2Zo  
R~[i{jY  
1 //解密函数  aJFBLik  
2 function myDecrypt($string, $key) ~[]NR#CF  
3 { kW @GSJx  
4 for($i=0; $i<STRLEN($STRING); p $i )<> Kh$+6\.f  
5 { " #3xHC  
6 for($j=0; $j<STRLEN($KEY); p $j )<> .oY C/q=  
7 { Q;':  
8 $string[$i] = $key[$j]^$string[$i]; @d2mvH>V-  
9 } 1\*k2B$"W  
10 } _K!~>Jx  
11 return $string; &MK j~V-  
12 } KQ2ZrK"  
13 ?> &xPL<%D  
`ZRZ0'JI7  
  第4行定义了解密函数myDecrypt (),输入参数$string为密文,而$key为密钥;输出为使用$key作为密钥并使用XOR解密算法产生的明文。 8k5O  
&$Eg @K  
  下面,通过一个应用示例来进一步说明加密函数的功能。 (thL!65  
a9{5Bk  
1 //示例 shG'|HZ_  
2 $my_password="chair"; b3^! Z1#  
3 echo "my_password = $my_password"; 4~\RDd~&  
4 $my_key="1234567890"; ac/'^M!~  
5 $my_password_en=myEncrypt($my_password,$my_key); &^_9`f  
6 echo "my_password_en = $my_password_en"; M+2JE %x-  
7 $my_password_de=myDecrypt($my_password_en,$my_key); 0d5DGLI  
8 echo "my_password_de = $my_password_de"; oJ__xe]K'  
#'hKTe#(0  
  第3行首先定义了一个明文$my_password,然后在第4行定义密钥$my_key。 Y}'(? .1,  
d!&e0MSS  
  第5、6行分别调用加密函数生成密文并输出;反过来,又在第7、8行将密文解密。 WVF,]/X  
<"Pk&  
  上面示例的运行结果如下。 A%PbYk  
(MBk 7r1  
  my_password = chair `>LW('D~e  
V "P1D  
  my_password_en = RYPXC *?f2m2  
(`Q>^R==&  
  my_password_de = chair ra!9P  
a-S'yyn^Yu  
  用XOR算法实现身份验证 6fK oA 4\  
iI >-.cdY  
  上两部分分别介绍了使用XOR运算进行信息加密/解密的原理和实现,下面,将使用这一方法来对用户的登录密码进行加密。本例中,为了保护用户的密码,系统想要达到的目的如下。 ~v}v3[   
C#d (Wm  
  ·在用户注册时,用户需要添写用户密码表单。 CGEECFs2:m  
^U9nHa04s  
  ·除用户本人之外,其他任何人都无法获取其密码信息,包括系统设计者和数据库管理员。 :L7Cry  
i+^Dm=C'  
  ·系统能根据用户输入的密码验证用户的合法性。 !PtZc<  
4y[7p8HD  
  为了达到以上目的,使用XOR算法时可以选择用户名作为明文,而密钥是用户自定义的密码,然后将加密后的用户名存储在数据库中。 8W_L3_M  
Ja3eBcVLFC  
  另外,在用户登录的时候,有以下两种方式来验证合法用户。  
4_3_Y7+E  
  (1)根据其提交的用户名(明文)和密码(密钥)信息重新加密,并使用加密后的信息与数据库中存储的密码信息进行比较,如果相等,则用户合法,否则,为非法用户。 qBv/r M  
! /rI6ly  
  (2)根据数据库中存储的密码信息(明文)和用户输入的密码(密钥)信息进行解密,并把加密后的信息与用户提交的用户名进行比较,如果相等,则用户合法,否则,为非法用户。 mcUb?fVsc  
oTqKDG nv  
  两种方式都可以实现第3个目的,本例,将采用第2种方式。本例的实现代码可在18.4.1节“用户登录”和18.4.2节“检查用户”的实现基础之上实现,其中“用户登录”页面无需变化,“检查用户”的实现参考如下。 |0 #Uix  
)J, U qE  
1 <?php za 6xKIL  
2 session_start(); //装载Session库,一定要放在首行 !}GI<   
3 $user_name=$_POST["user_name"]; ; L!19 8ak  
4 session_register("user_name"); //注册$user_name变量,注意没有$符号 RYXUycz:  
5 &HYU0h  
6 require_once("sys_conf.inc"); //系统配置文件,包含数据库配置信息 BkT.5*UHk  
7 require_once("encrypy_xor.php"); //包含xor加密函数文件 G""=@G7  
8 >hTmtIS  
9 //连接数据库 "h1{kym4  
10 $link_id=mysql_connect($DBHOST,$DBUSER,$DBPWD); YaU/ _V4  
11 mysql_select_db($DBNAME); //选择数据库my_chat 6ELX+.nwb!  
12 y!z2dlA /  
13 //查询是否存在登录用户信息 44d >)3"`]  
14 $str="select name,password from user where name ='$user_name'"; AS(FX};}  
15 $result=mysql_query($str,$link_id); //执行查询 "sFw8(8y  
16 @$rows=mysql_num_rows($result); //取得查询结果的记录笔数 R}|3\L`R  
17 $user_name=$_SESSION["user_name"]; Vl*N2jn  
18 $password=$_POST["password"]; D KpI2  
19 $password_en=myEncrypt($user_name,$password); //加密用户信息 Jb"j/akp  
20 UVrOPEOV  
21 //对于老用户 tyLj0L/  
22 if($rows!=0) W'iok3abA  
23 { +j8_,u  
24 list($name,$pwd)=mysql_fetch_row($result); 5usP-9/!^  
25 $password_de=myDecrypt($pwd,$password); //解密用户信息 HND[Fhr  
26 4[!@| R'a|  
27 //如果密码输入正确 Q$]OM0  
28 if($user_name==$password_de) ~B{Q  
29 { eZ Wo6O  
30 $str="update user set is_online =1 where name ='$user_name' and password='$password_en'"; 6JB+t3xT/  
31 $result=mysql_query($str, $link_id); //执行查询 x) 0n"j  
32 require("main.php"); //转到聊天页面 |gfR[F|Y  
33 } AeV~^A+!3  
34 //密码输入错误 "[08G^xU  
35 else E s g)b 6  
36 { z_sj>B?h  
37 require("relogin.php"); YjpKg9ar  
38 } r`%YAHh  
39 } ^b? &z\  
40 //对于新用户,将其信息写入数据库 KPpXwg H*  
41 else D|'X)bs  
42 { ] 6Izh  
43 $str="insert into user (name,password,is_online) values('$user_name', '$password_en',1)"; F4]>)x_  
44 $result=mysql_query($str, $link_id); //执行查询 "[Shc>  
45 require("main.php"); //转到聊天页面 o`lI{VsLJu  
46 } \F4 ;8 E%l  
47 //关闭数据库 O uissYJH  
48 mysql_close($link_id); oV{ jka  
49 ?> O%H5[  
&ge?hP.Y&  
  第7行引入了加密函数文件encrypy_xor.php,包括上一小节介绍的两个函数。 {G 6,"GR  
;r{pp[rV  
  第19行,使用用户提交的用户名和密码得到加密后的密码值,并且对于新用户,在第44行将这个加密后的值存储在数据库中。 o5+@r  
=Ai NF  
  另外,对于老用户,在第24获取数据库中用户名和加密后的密码信息,并在25行利用这两个值进行解密,然后在第28行通过比较解密后的值与用户提交的用户名信息来检查用户的合法性。 XXt,  
z]2Gr$y  
  自动生成密钥 | snig4N  
>R; ZG7  
  上一部分介绍了如何使用XOR加密算法进行对用户信息的加密,其中,用户所输入的口令信息实际上成为了加密算法中的密钥,而用户名作为明文使用,虽然这能很好地完成功能,但是在逻辑上,这种方法似乎有些不合理。 dn"q[|pM  
Lb IR# *  
  本文将介绍一种自动生成密钥的技术,可以使用自动生成的密钥对用户提交的密码明文加密,使逻辑更加合理一些。  
o *qHt3va  
  本例,假设生成的密钥为512位。代码如下。 77&wzrW  
q}v(cw3C  
1 <!--keygen.php:自动生成密钥------------------------------------> bRgk|bwg  
2 <?php Owgu0Uf)  
3 \L<,gx8y  
4 //自动生成长度为$len的密钥 2D{/d 
5 function generate_key($len) BueQy  
6 { x.7GzW){  
7 $lowerbound = 35 ; Gh~EG[\  
8 $upperbound = 96 ; "[]DJ  
9 $strMyKey = ""; zZ2v^(P`}D  
10  _:he  
11 for($i=1;$i<=$len;$i ) lXHXZQ?Z'  
12 { s<7p ])}}  
13 $rnd=rand(0,100); //产生随机数 .]tou(7  
14 $k = (($upperbound - $lowerbound) 1) * $rnd $lowerbound; K_Ls1,]  
15 $strMyKey=$strMyKey.$k; )xrC/14i  
16 } B,KY_=;  
17 return $strMyKey; O2+WZN@Tw9  
18 } pYcx!pR  
19 Aw<[}p|}gw  
20 //将密钥写入文件$file_name jwW.tf9x \  
21 function write_key($key,$file_name) 3?$@A+*D  
22 { hHHlN}q.lu  
23 $filename="C:\key.txt"; ;LmRZ  
24 $key=generate_key($key,512); pf*%Dn2y  
25 }}S`Meh O  
26 //使用添加模式打开$filename,文件指针将会在文件的末尾 N,k.j2K  
27 if(!$handle=fopen($filename,'w')) ^g>brFaws  
28 { =^SF(xk{  
29 print"不能打开文件$filename"; uy3'v%  
30 exit; 5%C~\nA0VZ  
31 } g ]s&l  
32 abp7$*  
33 //将$key写入到我们打开的文件中。 ovIJ`hv Xx  
34 if(!fwrite($handle,$key)) 't?l{JK%  
35 { >NM?C  
36 print"不能写入到文件$filename"; kIx.4>D  
37 exit; 9vX*:/<x  
38 } J'RfLoh^&-  
39 fclose($handle); m:]#  
40 } a (hm_Klt  
41 =rnhkD$_)  
42 //读取密钥文件中的密钥 I'=R)=u=  
43 function get_key($file_name) Ei(nk]  
44 { ^pe_ Q1Q2  
45 //打开文件 F='QTU1_  
46 $fp = fopen ($file_name, "r"); w:a"|@j  
47 $result="";  
48 //逐行读取 Y>'C6_oc  
49 while (!feof($fp)) <*O;:hZpS]  
50 { p.:7VDIr  
51 $buffer = fgets($fp, 4096); w<`[:Q[QpN  
52 $result=$result.$buffer; YIBG>9o  
53 } ]1y! *  
54 return $result; gD,* %(H  
55 } 5T;9wAZ   
56 ;n-zx%lzb  
57 ///* kXM7j+Zo  
58 $KeyLocation = "C:\key.txt"; //保存密钥的文件 )zMZ_&8s=  
59 $key="123456"; vC, .)h  
60 write_key($key,$KeyLocation); q6@Zy vyV  
61 echo get_key($KeyLocation); @Z[xmdP(  
62 //*/ jL&]X  
63 ?> ~{:IH&vE  
}ZwY;A)  
  代码包括3个函数。 dYLb?  
1 zM~L)@  
  ·generate_key($len):自动生成长度为$len的密钥 %vjY*&nM  
jIrj,KK  
  ·write_key($key,$file_name):将密钥写入文件$file_name .}R9lx XL  
vO?/>KL+  
  ·get_key($file_name):读取密钥文件$file_name中的密钥值 BEB $yU'H  
39./0h\  
  在使用时,当用户第一次登录系统时,自动为其生成密钥值,对于这个密钥值,可以有两种方式来处理。 hs36'  
Lj1et_w$.  
  (1)将其存入数据库的某个字段中,这种方法的缺点是密钥在数据库中的安全性无法得到保证; .7!w, /@9@  
,eE$wu  
  (2)将这个密钥保存在用户本地的文件中,这样就可以避免密钥被别人获取,但这种方式的缺点是,当用户使用其他机器访问系统时,就无法登录。 d9rMP  
-R)+Nm2#  
  本例中,将使用第2种方式。 q5(Q pw  
Dr^64p6  
  具体地,上面代码第11~18行通过生成随机数的方式来不断生成密钥,并通过一个计算来增强其复杂性。其中的lowerbound和upperbound的数值其实就是你想使用来加密的ASCII字符范围。下面是生成的一个密钥文件示例。 kUr 9  
[Ig6u - y>  
  208123915925183361116049369344372701567721435181102718332639307390344373445407 [ac-YFHE  
x1+=y>7  
  524316475863232913993383189547474747394154915312639841226741894189965623523913 nsF|{5_-!t  
iq+JvQ :F  
  011164730113445201935692839710274127251577929493941487145611337531549110895367 hKl%ZLcA  
+q 
  593586318332391170941272701152344371709270125776235313540032267139933835677407 _wuN28y}  
NCsR%p0O  
  617384135696111239130732949469623520815987524358635491542913374933524334454251 v7vz'" b^  
y-byONIo8  
  400327015367133759324537171709152357391089524342514685239122673135531363151191 l_(I#4f   
R5QB5@JNH  
  833412771743139654… rZc"xp"  
Lca# )K ]=  
  最后,需要把密钥保存在服务器上一个安全的地方,然后就可以利用其和诸如XOR这样的加密算法来对用户信息进行加密/解密了。
阅读(370) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~