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

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中使用这个密钥非常简单,不再详述。

(0)

相关推荐

  • PHP 加密解密内部算法

    将它们打包成一个文件就叫fun.php吧 复制代码 代码如下: <?php function passport_encrypt($txt, $key) { srand((double)microtime() * 1000000); $encrypt_key = md5(rand(0, 32000)); $ctr = 0; $tmp = ''; for($i = 0;$i < strlen($txt); $i++) { $ctr = $ctr == strlen($encrypt_key) ?

  • php实现rc4加密算法代码

    代码 复制代码 代码如下: /* * rc4加密算法 * $pwd 密钥 * $data 要加密的数据 */ function rc4 ($pwd, $data)//$pwd密钥 $data需加密字符串 { $key[] =""; $box[] =""; $pwd_length = strlen($pwd); $data_length = strlen($data); for ($i = 0; $i < 256; $i++) { $key[$i] = ord(

  • php对称加密算法示例

    php对称加密算法 KEY 是之前定义的常量 复制代码 代码如下: Mcrypt::encrypt();Mcrypt::decrypt(); 复制代码 代码如下: defined('ROOT') or exit('Access Denied'); class Mcrypt{ public static function encrypt($code){  return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5(KEY), $code

  • 一组PHP可逆加密解密算法实例代码

    对于大部分密码加密,我们可以采用md5.sha1等方法.可以有效防止数据泄露,但是这些方法仅适用于无需还原的数据加密. 对于需要还原的信息,则需要采用可逆的加密解密算法. 下面一组PHP函数是实现此加密解密的方法: 加密算法如下: 复制代码 代码如下: function encrypt($data, $key){ $key = md5($key);    $x  = 0;    $len = strlen($data);    $l  = strlen($key);    for ($i = 0

  • 通过PHP的内置函数,通过DES算法对数据加密和解密

    由于项目的需要,要写一个能生成"授权码"的类(授权码主要包含项目使用的到期时间),生成的授权码将会写入到一个文件当中,每当项目运行的时候,会自动读取出文件中的密文,然后使用唯一的"密钥"来调用某个函数,对密文进行解密,从中解读出项目的使用到期时间. 之前,自己有先试着写了下,主要是base64+md5+反转字符串.算法太过简单,很容易被破解,而且也没有能过做到"密钥"在加解密中的重要性,故而舍之. 后来,查找了相关资料,发现,原来PHP中内置了一

  • PHP实现AES256加密算法实例

    本文实例讲述了PHP实现AES256加密算法的方法,是较为常见的一种加密算法.分享给大家供大家参考.具体如下: aes.class.php文件如下: <?php /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* AES implementation in PHP (c) Chris Veness 2005-2011. Right of fre

  • PHP对称加密函数实现数据的加密解密

    项目中有一个地方用到了将用户ID加密.传至下个接点进行反解的需求.(原谅我不能透漏太多-_-!),第一个想到的就是康盛Ucenter中的一个函数,后来搜了下,在简明魔法中也找到了个简单的方法,遂整合了下,形成了自己使用的函数. 一.对称加密 发送方将明文使用密钥和算法处理成密文发送出去,接收方使用密钥和算法将密文处理成明文,发收信双方使用同一个密钥对数据进行加密和解密. 因为使用同一个密钥加密.解密,所以安全性上不仅与算法有关,密钥的安全也很重要. 当然并不是密钥越复杂越好,相反密钥通常比较小的

  • php加密算法之实现可逆加密算法和解密分享

    加密算法如下: 复制代码 代码如下: function encrypt($data, $key){ $key = md5($key);    $x  = 0;    $len = strlen($data);    $l  = strlen($key);    for ($i = 0; $i < $len; $i++)    {        if ($x == $l)         {         $x = 0;        }        $char .= $key{$x};   

  • php中简单的对称加密算法实现

    前言 在网上找到了一个不错的PHP方面的对称加密算法:在PHP的语法环境里,有urlencode与urldecode,base64_encode和base64_decode自带的对称算法,不过这些自带的算法不能称之为加密算法,只能说是编码方式而已.可是我们可以利用这些来进行一些加工,来实现简单的加密和解密算法. 这次的加密和解密算法是使用base64的方式改编的.通常我们使用base64_encode($str)产生的字符串,不经过任何的加工的话,base64_decode()就能转回我们之前的

  • PHP中对各种加密算法、Hash算法的速度测试对比代码

    PHP 的Hash算法是比较常用的,现在的MD5有时候不太安全,就得用到Hash_algos()中的其它算法,下面进行了一个性能的比较. php代码: define('testtime', 50000); $algos = hash_algos(); foreach($algos as $algo) { $st = microtime(); for($i = 0; $i < testtime; $i++) { hash($algo, microtime().$i); } $et = microt

随机推荐