Discuz(php)的加密算法


Posted on November 26, 2008


私有密匙(passport_key)

由于一些关键参数采用了 GET 方式进行传递,即便两次 header 跳转并不会直接将链接显示在外面,但我们仍然对关键的参数进行了加密,私有 密匙共有两个作用:其一是供下面提到的可逆加密算法(AzDGCrypt)进行数据的加解密。其二是生成不可逆验证字串(verify),以防止关键信息被 伪造。

在启用 Discuz! Passort 后,您需要在应用程序和 Discuz! 后台配置两处私有密匙,这两处的内容必须完全相同,这样应用程序和论坛之间才能 正常通信。私有密匙决定了加密算法的强度,因此密匙长度请不要小于 10 个字节,并包含字母、数字和符号,以保证系统的安全。

加密算法

Discuz! Passport 采用 Azerbaijan Development Group(AzDG)开发的可逆加密算法 AzDGCrypt 对用户资料进行加密。如提供正确的私有密匙, 可通过本加密算法对数据进行加密及解密,因此只要保证私有密匙的保密性,即可确保数据传递过程中的安全。以下为 Discuz! Passport 中应用到 的可逆加密算法,为了生成可以被 Discuz! Passport 正确解密的 auth 字串,需要将如下函数放置于应用程序中,并可在登录及注册时调用。

passport_encrypt()是加密函数,用法为 passport_encrypt($txt, $key),其中 $txt 是待加密的字串,$key 是私有密匙。
passport_decrypt()是解密函数,用法为 passport_decrypt($txt, $key),其中 $txt 是加密后的字串,$key 是私有密匙。  

/**
* Passport 加密函数
*
* @param  string  等待加密的原字串
* @param  string  私有密匙(用于解密和加密)
*
* @return string  原字串经过私有密匙加密后的结果
*/
function passport_encrypt($txt, $key) {
 // 使用随机数发生器产生 0~32000 的值并 MD5()
 srand((double)microtime() * 1000000);
 $encrypt_key = md5(rand(0, 32000));
 // 变量初始化
 $ctr = 0;
 $tmp = '''';
 // for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
 for($i = 0; $i < strlen($txt); $i++) {
  // 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
  $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
  // $tmp 字串在末尾增加两位,其第一位内容为 $encrypt_key 的第 $ctr 位,
  // 第二位内容为 $txt 的第 $i 位与 $encrypt_key 的 $ctr 位取异或。然后 $ctr = $ctr + 1
  $tmp .= $encrypt_key[$ctr].($txt[$i] ^ $encrypt_key[$ctr++]);
 }
 // 返回结果,结果为 passport_key() 函数返回值的 base64 编码结果
 return base64_encode(passport_key($tmp, $key));
}
/**
* Passport 解密函数
*
* @param  string  加密后的字串
* @param  string  私有密匙(用于解密和加密)
*
* @return string  字串经过私有密匙解密后的结果
*/
function passport_decrypt($txt, $key) {
 // $txt 的结果为加密后的字串经过 base64 解码,然后与私有密匙一起,
 // 经过 passport_key() 函数处理后的返回值
 $txt = passport_key(base64_decode($txt), $key);
 // 变量初始化
 $tmp = '''';
 // for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
 for ($i = 0; $i < strlen($txt); $i++) {
  // $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
  // 与 $txt 的第 $i + 1 位取异或。然后 $i = $i + 1
  $tmp .= $txt[$i] ^ $txt[++$i];
 }
 // 返回 $tmp 的值作为结果
 return $tmp;
}
/**
* Passport 密匙处理函数
*
* @param  string  待加密或待解密的字串
* @param  string  私有密匙(用于解密和加密)
*
* @return string  处理后的密匙
*/
function passport_key($txt, $encrypt_key) {
 // 将 $encrypt_key 赋为 $encrypt_key 经 md5() 后的值
 $encrypt_key = md5($encrypt_key);
 // 变量初始化
 $ctr = 0;
 $tmp = '''';
 // for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
 for($i = 0; $i < strlen($txt); $i++) {
  // 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
  $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
  // $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
  // 与 $encrypt_key 的第 $ctr + 1 位取异或。然后 $ctr = $ctr + 1
  $tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
 }
 // 返回 $tmp 的值作为结果
 return $tmp;
}
/**
* Passport 信息(数组)编码函数
*
* @param  array  待编码的数组
*
* @return string  数组经编码后的字串
*/
function passport_encode($array) {
 // 数组变量初始化
 $arrayenc = array();
 // 遍历数组 $array,其中 $key 为当前元素的下标,$val 为其对应的值
 foreach($array as $key => $val) {
  // $arrayenc 数组增加一个元素,其内容为 "$key=经过 urlencode() 后的 $val 值"
  $arrayenc[] = $key.''=''.urlencode($val);
 }
 // 返回以 "&" 连接的 $arrayenc 的值(implode),例如 $arrayenc = array(''aa'', ''bb'', ''cc'', ''dd''),
 // 则 implode(''&'', $arrayenc) 后的结果为 ”aa&bb&cc&dd"
 return implode(''&'', $arrayenc);

passport_encode()是将数组转换合成为字串形式存储的函数:变量名和数值之间用等号连接,如果数值包含特殊字符,使用 urlencode() 将其转码。 多个变量间使用 & 分割。例如原始数组内容为 array(''username'' => ''abc'', ''email'' => ''my+discuz@gmail.com''),经过passport_encode() 编码后 结果为 username=abc&email=my%2Bdiscuz%40gmail.com。
 


标签:N/A

其它推荐日志:

RegularExpressionValidator控件

Visual Web Developer 2005 速成版 生成DLL的问题

必须学会的几个网络测试命令

介绍一个web2.0站点模板

IIS装framework 2.0

sql语句中不能随便回车

【转】char、varchar、nchar、nvarchar的区别

C#获取程序当前路径的方法

php文件上传方法和处理过程

memcpy用法

学习ajax-xmlhttp:open方法

GridView鼠标经过行变色

sql数据库连接串中的pooling=true和pooling=false的区别

开始→运行→命令集锦

Android环境搭建笔记

fatal error C1853

什么是僵尸文件?

ASP.NET图片防盗链的方法

Sun:Java+Vista没问题

HOW TO:利用 Visual C# .NET 使 Word 自动新建文档

关于ASP.NET中用Response.Write()方法响应导致页面字体变大的问题

asp判断session是否超时!

【FTP】批处理上传文件至FTP服务器上某个目录下

什么是WINPE系统?

在javascript中设置body的onload事件

PHP下载DOC文件出错乱码的解决方案

C#编码标准--编码习惯(转)

打到一个很有用的的显IP代码!分享一下!

无法将类型“ASP.Image_aspx”转换为“System.Web.UI.WebControls.Image”

在关键字 ''User'' 附近有语法错误。

细说HTML元素的ID和Name属性的区别

用c#读文件

纯真IP数据库格式详解

个人网站建设步骤

如何在asp.net中用c#在获得当前系统登陆的帐户的Identity

搜集几个免费ASP空间,不能保证其时效性,仅供参考实践用!

VS2005出现visual sourcesafe login窗口

关于“System.NullReferenceException: 未将对象引用设置到对象的实例”问题原因

买神舟笔记本需要注意的几点

C语言中的main函数参数及返回值


Search
最新评论
推荐日志
微信扫一扫