Discuz的passport与Perl版本的passpost[通用](1 位领导批示)
最近做的一个项目中 需要perl与php进行数据通信.我用LWP::UserAgent的POST方法实现了与PHP程序的连接.
不过在安全上有很大问题.找了找.DZ的passport就直接拿来用了..哇卡卡..
首先是Discuz的passport方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /** * 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); } |
这个当然不能直接在perl中使用..
再来看看Perl中的自定义passpost子程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | use Digest::MD5 qw(md5_hex); use MIME::Base64; #加密模块 sub passport_encrypt { my($txt, $key,$ctr,$tmp)=(shift,shift,0,undef); srand; my $encrypt_key = md5_hex(rand 32000); for(my $i = 0; $i < length($txt); $i++) { #如果 $ctr = $encrypt_key 的长度,则 $ctr 清零 $ctr = $ctr == length($encrypt_key) ? 0 : $ctr; #$tmp 字串在末尾增加两位,其第一位内容为 $encrypt_key 的第 $ctr 位, 第二位内容为 $txt 的第 $i 位与 $encrypt_key 的 $ctr 位取异或。然后 $ctr = $ctr + 1 $tmp .= substr($encrypt_key,$ctr,1).(substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1)); $ctr++; } #返回结果,结果为 passport_key() 函数返回值的 base64 编码结果 return encode_base64(passport_key($tmp, $key)); } #解密模块 sub passport_decrypt { my ($txt, $key,$tmp)=(shift,shift,undef); #$txt 的结果为加密后的字串经过 base64 解码,然后与私有密匙一起经过 passport_key() 函数处理后的返回值 $txt = passport_key(decode_base64($txt), $key); #for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数 for (my $i = 0; $i < length($txt); $i++) { # $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位与 $txt 的第 $i + 1 位取异或。然后 $i = $i + 1 $tmp .= substr($txt,$i,1) ^substr($txt,++$i,1); } #返回 $tmp 的值作为结果 return $tmp; } #密匙模块 sub passport_key { my ($txt, $encrypt_key,$ctr,$tmp)=(shift,shift,0,undef); #将 $encrypt_key 赋为 $encrypt_key 经 md5() 后的值 $encrypt_key = md5_hex($encrypt_key); #for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数 for(my $i = 0; $i < length($txt); $i++) { #如果 $ctr = $encrypt_key 的长度,则 $ctr 清零 $ctr = $ctr == length($encrypt_key) ? 0 : $ctr; #$tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位, 与 $encrypt_key 的第 $ctr + 1 位取异或。然后 $ctr = $ctr + 1 $tmp .= substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1); $ctr++; } # 返回 $tmp 的值作为结果 return $tmp; } |
相关文章
NOTE:本博内容大部分为原创,转载请注明出处。
永久链接:http://www.zdyi.com/discuz_perl_passport/160


























崇拜技术