discuz通行证用对称密钥的加密,基于任何一数与结果异或必然获得另外一个数,因此是一个可逆的算法,使用密钥的每位轮回加密数据的每位.
passport_encrypt函数使用时随机数来加密,而后把密钥放在密文的前面,最后调用的passport_key才是真正的加密解密函数,那为何这样作?密钥和密文放在一块儿看起来没用,我刚开始也这么想,后来发现这偏偏是最重要的,由于是基于异或加密,也就是说,用户知道任意两个数就能够获得第三个数,当用户输一个明文进去,获得一个密文,再异或就能获得密钥,这是不被容许,discuz是如何防止的?采用随机数,而后MD5,接在与用户输入的前面,这样用户就不知道本身的输入,固然他能够试,每个数有三十六个可能,discuzMD5了一下密钥,要试36的32的方,并且这样也只是获得了一个MD5,逻辑上不大可能.
要作首页和论坛的通行证了,因此分析一下这个,可能那边要在jsp上面实现吧.哎
/*** Passport 加密函数** @param string 等待加密的原字串* @param string 私有密匙(用于解密和加密)** @return string 原字串通过私有密匙加密后的结果*/function passport_encrypt($txt, $key) {//R 使用随机数加密,密钥放在字符前面// 使用随机数发生器产生 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() 函数返回值的 base65 编码结果return base64_encode(passport_key($tmp, $key)); //R 真正使用密码加密}/*** Passport 解密函数** @param string 加密后的字串* @param string 私有密匙(用于解密和加密)** @return string 字串通过私有密匙解密后的结果*/function passport_decrypt($txt, $key) {// $txt 的结果为加密后的字串通过 base64 解码,而后与私有密匙一块儿,// 通过 passport_key() 函数处理后的返回值$txt = passport_key(base64_decode($txt), $key); //R 二次加密就是解密// 变量初始化$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]; R //解密随机加密;}// 返回 $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; //R 轮// $tmp 字串在末尾增长一位,其内容为 $txt 的第 $i 位,// 与 $encrypt_key 的第 $ctr + 1 位取异或。而后 $ctr = $ctr + 1$tmp .= $txt[$i] ^ $encrypt_key[$ctr++]; //R 轮翻异或加密; }// 返回 $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);}