PHP MySQL应用中使用XOR运算加密算法分享


Posted in PHP onAugust 28, 2011

XOR算法原理

从加密的主要方法看,换位法过于简单,特别是对于数据量少的情况很容易由密文猜出明文,而替换法不失为一种行之有效的简易算法。

从各种替换法运算的特点看,异或运算最适合用于简易加解密运算,这种方法的原理是:当一个数A和另一个数B进行异或运算会生成另一个数C,如果再将C和B进行异或运算则C又会还原为A。

相对于其他的简易加密算法,XOR算法的优点如下。

(1)算法简单,对于高级语言很容易能实现。

(2)速度快,可以在任何时候、任何地方使用。

(3)对任何字符都是有效的,不像有些简易加密算法,只对西文字符有效,对中文加密后再解密无法还原为原来的字符。

XOR算法实现

上一部分介绍了如何使用XOR运算进行加密/解密的原理,本节将使用其加密用户的登录信息。根据上一小节介绍的XOR加密算法的原理,不难写出以下的加密解密函数。首先列出加密算法。

<!?encrypy_xor:简单使用XOR运算的加密函数———————?> 
<?php 
//加密函数 
functionmyEncrypt($string,$key) 
{ 
for($i=0;$i<STRLEN($STRING);p$i++)<> 
{ 
for($j=0;$j<STRLEN($KEY);p$j++)<> 
{ 
$string[$i]=$string[$i]^$key[$j]; 
} 
} 
return$string; 
}

第4行定义了加密函数myEncrypt(),输入参数$string为明文,而$key为密钥;输出为使用$key作为密钥并使用XOR加密算法产生的密文。
第6~12行的外层for循环对明文字符串的每一个字符进行循环,而内层的for循环(第8~11行)对明文的每一字符循环与密钥的每一位做异或运算。其原理已经在上一小节中介绍,不再重述。
同样,与加密函数类似,可以写出下面的解密函数。
//解密函数 
functionmyDecrypt($string,$key) 
{ 
for($i=0;$i<STRLEN($STRING);p$i++)<> 
{ 
for($j=0;$j<STRLEN($KEY);p$j++)<> 
{ 
$string[$i]=$key[$j]^$string[$i]; 
} 
} 
return$string; 
} 
?>

第4行定义了解密函数myDecrypt(),输入参数$string为密文,而$key为密钥;输出为使用$key作为密钥并使用XOR解密算法产生的明文。
下面,通过一个应用示例来进一步说明加密函数的功能。
//示例 
$my_password="chair"; 
echo"my_password=$my_password"; 
$my_key="1234567890″; 
$my_password_en=myEncrypt($my_password,$my_key); 
echo"my_password_en=$my_password_en"; 
$my_password_de=myDecrypt($my_password_en,$my_key); 
echo"my_password_de=$my_password_de";

第3行首先定义了一个明文$my_password,然后在第4行定义密钥$my_key。
第5、6行分别调用加密函数生成密文并输出;反过来,又在第7、8行将密文解密。
上面示例的运行结果如下。
my_password=chair
my_password_en=RYPXC
my_password_de=chair
用XOR算法实现身份验证
上两部分分别介绍了使用XOR运算进行信息加密/解密的原理和实现,下面,将使用这一方法来对用户的登录密码进行加密。本例中,为了保护用户的密码,系统想要达到的目的如下。
·在用户注册时,用户需要添写用户密码表单。
·除用户本人之外,其他任何人都无法获取其密码信息,包括系统设计者和数据库管理员。
·系统能根据用户输入的密码验证用户的合法性。
为了达到以上目的,使用XOR算法时可以选择用户名作为明文,而密钥是用户自定义的密码,然后将加密后的用户名存储在数据库中。
另外,在用户登录的时候,有以下两种方式来验证合法用户。
(1)根据其提交的用户名(明文)和密码(密钥)信息重新加密,并使用加密后的信息与数据库中存储的密码信息进行比较,如果相等,则用户合法,否则,为非法用户。
(2)根据数据库中存储的密码信息(明文)和用户输入的密码(密钥)信息进行解密,并把加密后的信息与用户提交的用户名进行比较,如果相等,则用户合法,否则,为非法用户。
两种方式都可以实现第3个目的,本例,将采用第2种方式。本例的实现代码可在18.4.1节“用户登录"和18.4.2节“检查用户"的实现基础之上实现,其中“用户登录"页面无需变化,“检查用户"的实现参考如下。
<?php 
session_start();//装载Session库,一定要放在首行 
$user_name=$_POST["user_name"]; 
session_register(“user_name");//注册$user_name变量,注意没有$符号 
require_once(“sys_conf.inc");//系统配置文件,包含数据库配置信息 
require_once(“encrypy_xor.php");//包含xor加密函数文件 
//连接数据库 
$link_id=mysql_connect($DBHOST,$DBUSER,$DBPWD); 
mysql_select_db($DBNAME);//选择数据库my_chat 
//查询是否存在登录用户信息 
$str="selectname,passwordfromuserwherename='$user_name'"; 
$result=mysql_query($str,$link_id);//执行查询 
@$rows=mysql_num_rows($result);//取得查询结果的记录笔数 
$user_name=$_SESSION["user_name"]; 
$password=$_POST["password"]; 
$password_en=myEncrypt($user_name,$password);//加密用户信息 
//对于老用户 
if($rows!=0) 
{ 
list($name,$pwd)=mysql_fetch_row($result); 
$password_de=myDecrypt($pwd,$password);//解密用户信息 
//如果密码输入正确 
if($user_name==$password_de) 
{ 
$str="updateusersetis_online=1wherename='$user_name'andpassword='$password_en'"; 
$result=mysql_query($str,$link_id);//执行查询 
require(“main.php");//转到聊天页面 
} 
//密码输入错误 
else 
{ 
require(“relogin.php"); 
} 
} 
//对于新用户,将其信息写入数据库 
else 
{ 
$str="insertintouser(name,password,is_online)values(‘$user_name','$password_en',1)"; 
$result=mysql_query($str,$link_id);//执行查询 
require(“main.php");//转到聊天页面 
} 
//关闭数据库 
mysql_close($link_id); 
?>

第7行引入了加密函数文件encrypy_xor.php,包括上一小节介绍的两个函数。
第19行,使用用户提交的用户名和密码得到加密后的密码值,并且对于新用户,在第44行将这个加密后的值存储在数据库中。
另外,对于老用户,在第24获取数据库中用户名和加密后的密码信息,并在25行利用这两个值进行解密,然后在第28行通过比较解密后的值与用户提交的用户名信息来检查用户的合法性。
自动生成密钥
上一部分介绍了如何使用XOR加密算法进行对用户信息的加密,其中,用户所输入的口令信息实际上成为了加密算法中的密钥,而用户名作为明文使用,虽然这能很好地完成功能,但是在逻辑上,这种方法似乎有些不合理。
本文将介绍一种自动生成密钥的技术,可以使用自动生成的密钥对用户提交的密码明文加密,使逻辑更加合理一些。
本例,假设生成的密钥为512位。代码如下。
<!?keygen.php:自动生成密钥————————————> 
<?php 
//自动生成长度为$len的密钥 
functiongenerate_key($len) 
{ 
$lowerbound=35; 
$upperbound=96; 
$strMyKey=""; 
for($i=1;$i<=$len;$i++) 
{ 
$rnd=rand(0,100);//产生随机数 
$k=(($upperbound-$lowerbound)+1)*$rnd+$lowerbound; 
$strMyKey=$strMyKey.$k; 
} 
return$strMyKey; 
} 
//将密钥写入文件$file_name 
functionwrite_key($key,$file_name) 
{ 
$filename="C:\key.txt"; 
$key=generate_key($key,512); 
//使用添加模式打开$filename,文件指针将会在文件的末尾 
if(!$handle=fopen($filename,'w')) 
{ 
print"不能打开文件$filename"; 
exit; 
} 
//将$key写入到我们打开的文件中。 
if(!fwrite($handle,$key)) 
{ 
print"不能写入到文件$filename"; 
exit; 
} 
fclose($handle); 
} 
//读取密钥文件中的密钥 
functionget_key($file_name) 
{ 
//打开文件 
$fp=fopen($file_name,"r"); 
$result=""; 
//逐行读取 
while(!feof($fp)) 
{ 
$buffer=fgets($fp,4096); 
$result=$result.$buffer; 
} 
return$result; 
} 
///* 
$KeyLocation="C:\key.txt";//保存密钥的文件 
$key="123456″; 
write_key($key,$KeyLocation); 
echoget_key($KeyLocation); 
//*/ 
?>

代码包括3个函数。
◆ generate_key($len):自动生成长度为$len的密钥
◆ write_key($key,$file_name):将密钥写入文件$file_name
◆ get_key($file_name):读取密钥文件$file_name中的密钥值
在使用时,当用户第一次登录系统时,自动为其生成密钥值,对于这个密钥值,可以有两种方式来处理。
(1)将其存入数据库的某个字段中,这种方法的缺点是密钥在数据库中的安全性无法得到保证;
(2)将这个密钥保存在用户本地的文件中,这样就可以避免密钥被别人获取,但这种方式的缺点是,当用户使用其他机器访问系统时,就无法登录。
本例中,将使用第2种方式。
具体地,上面代码第11~18行通过生成随机数的方式来不断生成密钥,并通过一个计算来增强其复杂性。其中的lowerbound和upperbound的数值其实就是你想使用来加密的ASCII字符范围。下面是生成的一个密钥文件示例。
208123915925183361116049369344372701567721435181102718332639307390344373445407
524316475863232913993383189547474747394154915312639841226741894189965623523913
011164730113445201935692839710274127251577929493941487145611337531549110895367
593586318332391170941272701152344371709270125776235313540032267139933835677407
617384135696111239130732949469623520815987524358635491542913374933524334454251
400327015367133759324537171709152357391089524342514685239122673135531363151191
833412771743139654…
最后,需要把密钥保存在服务器上一个安全的地方,然后就可以利用其和诸如XOR这样的加密算法来对用户信息进行加密/解密了。如何在上一部分介绍的XOR中使用这个密钥非常简单,不再详述。
PHP 相关文章推荐
php中用文本文件做数据库的实现方法
Mar 27 PHP
php UTF8 文件的签名问题
Oct 30 PHP
PHP 设置MySQL连接字符集的方法
Jan 02 PHP
php引用返回与取消引用的详解
Jun 08 PHP
深入PHP变量存储的详解
Jun 13 PHP
php操作redis中的hash和zset类型数据的方法和代码例子
Jul 05 PHP
PHP判断文章里是否有图片的简单方法
Jul 26 PHP
PHP中的命名空间相关概念浅析
Jan 22 PHP
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
Jan 07 PHP
基于命令行执行带参数的php脚本并取得参数的方法
Jan 25 PHP
php正则表达式验证(邮件地址、Url地址、电话号码、邮政编码)
Mar 14 PHP
[原创]php正则删除img标签的方法示例
May 27 PHP
PHP 时间日期操作实战
Aug 26 #PHP
PHP url 加密解密函数代码
Aug 26 #PHP
php图片上传存储源码并且可以预览
Aug 26 #PHP
PHP 无限分类三种方式 非函数的递归调用!
Aug 26 #PHP
php中将图片gif,jpg或mysql longblob或blob字段值转换成16进制字符串
Aug 23 #PHP
PHP数组实例总结与说明
Aug 23 #PHP
JpGraph php柱状图使用介绍
Aug 23 #PHP
You might like
ecshop实现smtp发送邮件
2015/02/03 PHP
php mysql procedure实现获取多个结果集的方法【基于thinkPHP】
2016/11/09 PHP
PHP利用百度ai实现文本和图片审核
2019/05/08 PHP
Thinkphp 框架配置操作之配置加载与读取配置实例分析
2020/05/15 PHP
JavaScript 常见对象类创建代码与优缺点分析
2009/12/07 Javascript
IE下JS读取xml文件示例代码
2013/08/05 Javascript
一个奇葩的最短的 IE 版本判断JS脚本
2014/05/28 Javascript
javascript的事件触发器介绍的实现
2014/06/05 Javascript
jQuery+ajax实现鼠标单击修改内容的方法
2014/06/27 Javascript
js实现新浪微博首页效果
2015/10/16 Javascript
jquery trigger函数执行两次的解决方法
2016/02/29 Javascript
Jquery循环截取字符串的方法(多出的字符串处理成&quot;...&quot;)
2016/11/28 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
2018/11/27 Javascript
js 实现 list转换成tree的方法示例(数组到树)
2019/08/18 Javascript
JavaScript 替换所有匹配内容及正则替换方法
2020/02/12 Javascript
jQuery HTML获取内容和属性操作实例分析
2020/05/20 jQuery
vue 解决data中定义图片相对路径页面不显示的问题
2020/08/13 Javascript
html5以及jQuery实现本地图片上传前的预览代码实例讲解
2021/03/01 jQuery
零基础写python爬虫之爬虫的定义及URL构成
2014/11/04 Python
PyQt5 QSerialPort子线程操作的实现
2018/04/21 Python
python消除序列的重复值并保持顺序不变的实例
2018/11/08 Python
Laravel+Dingo/Api 自定义响应的实现
2019/02/17 Python
详解Python odoo中嵌入html简单的分页功能
2019/05/29 Python
Python多继承以及MRO顺序的使用
2019/11/11 Python
python实现将json多行数据传入到mysql中使用
2019/12/31 Python
台湾深度自由行旅游平台:Tripbaa趣吧
2017/10/10 全球购物
最便宜促销价格订机票:Airpaz(总部设在印尼,支持中文)
2018/11/13 全球购物
实习教师自我鉴定
2013/12/12 职场文书
《植物妈妈有办法》教学反思
2014/02/25 职场文书
调研汇报材料范文
2014/08/17 职场文书
2014年加油站站长工作总结
2014/12/23 职场文书
解决SpringCloud Feign传对象参数调用失败的问题
2021/06/23 Java/Android
mybatis3中@SelectProvider传递参数方式
2021/08/04 Java/Android
mysql sock文件存储了什么信息
2022/07/15 MySQL
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
2022/08/05 Vue.js
Nginx如何配置多个服务域名解析共用80端口详解
2022/09/23 Servers