急急急!!!!!authcode加密后,竟然出现部分解密不了了。。。。。。相当棘手啊~~!!!!!!!!!!

用户昵称不能为空 2010-09-06 10:55:05
有的时候遇到的问题真的是千奇百怪的,authcode 加密后竟然出现部分用户的解密不了,问题原因还是没有找到,目前出现这样的情况的概率是 1%~5%。

涉及文件:login.php 和 cp.php
涉及函数:authcode 和 ssetcookie

登陆过程描述:
用户登陆提交用户名、用户密码给login.php后,login.php写入cookie(使用的函数是ssetcookie)。
写入的有三个值,一个是 userid,一个是username,另外一个是password(其中仅password是通过authcode进行加密的,其他的都不加密)。
写入代码执行完成后,执行跳转到cp.php的代码,login.php代码执行完毕。
cp.php一打开代码就读取cookie,然后读取userid,username,password。将password解密,并且查询数据库是否有userid,password等于该值的用户。




但是到了验证这里就不行了,出现了两种问题
1.userid读取不了。有的用户的COOKIE值前面竟然加了一个英文状态下的逗号,我百思不得其解。他们的$_SERVER['HTTP_COOKIE']的值的第一个字符前竟然多了一个英文状态下的逗号,$_SERVER['HTTP_COOKIE']的值变成了, Kv5jT_userid=1068; Kv5jT_password=ad64dAqycMa8bgoQRxKE32DYn249SWTu6BD3kz8vfmP2m6v4tw; Kv5jT_username=xiaopengyou,所以他的userid无法读取成功,后来我在login.php程序里面修改了下,在设置cookie userid前,加设置了一个timestamp,因为timestamp前面多了一个英文状态下的逗号,当然timestamp就读取不了了,不过timestamp是不起作用的,所以第一个问题就这样解决了。

2.出现1%~3%的用户password解密不了。真的是百思不得其解。
password的加密是使用的discuz的authcode函数进行加密的,authcode函数全部源码如下:

//字符串解密加密,使用到的程序页面 login.php cp.php
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {

$ckey_length = 4; // 随机密钥长度 取值 0-32;
// 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
// 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
// 当此值为 0 时,则不产生随机密钥

$key = md5($key ? $key : $GLOBALS['_SG']['authkey']);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);

$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);

$result = '';
$box = range(0, 255);

$rndkey = array();
for($i = 0; $i <= 255; $i++)
{
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}

for($j = $i = 0; $i < 256; $i++)
{
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for($a = $j = $i = 0; $i < $string_length; $i++)
{
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if($operation == 'DECODE')
{
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16))
{
return substr($result, 26);
}
else
{
return '';
}
}
else
{
return $keyc.str_replace('=', '', base64_encode($result));
}
}


其中$_SG['authkey']的值原先使用的是 MD5($ip.$_SERVER['HTTP_USER_AGENT'])的值来进行计算的,但是使用 $_SG['authkey'] = md5($ip.$_SERVER['HTTP_USER_AGENT']);来生成函数 authcode 里面使用的密钥,竟然会出现
IE8 / IE7 登陆用户中 80% 以上的用户无法登录!!
我查看登陆失败的日志,发现他们的都是password无法解密,然后Firefox未发现一例这样的,然后我也检查了N次代码,都未发现问题,我判断这和浏览器有关,然后我发现IE内核的浏览器的$_SERVER['HTTP_USER_AGENT']的值相当长,为“Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; CIBA; TheWorld)”,所以我将$_SG['authkey']里面涉及的浏览器的$_SERVER['HTTP_USER_AGENT']的改为了 $_SERVER['HTTP_HOST']。这样IE内核的用户出现登陆不了的问题立即解决了。
但是这几天却仍旧出现了这样的password解密不了的问题(从登陆失败日志里面了解到的),登陆失败的日志里面仍旧有人userid,username,password这几个的COOKIE值都有,但是password这里解密结果是空的,也就是password解密不了。我将几条记录测试了一下,确实是password解密不了。


------------------------------------------------------
头都大了,不知道我描述的是否清楚,反正出现的问题就是password出现部分用户解密不了,而且基本上都是IE用户(但是访问网站的人/咱中国人 基本上都是用IE内核的浏览器,所以也不能说password解密不了和浏览器有关),但是说假如我的加密解密过程有错误的话,那么为什么不是100%的用户登录不了,而是部分 1%~3%的用户出现这样的情况呢?而我自己和公司的人使用IE内核 或者 Firefox浏览器都是可以登陆的,从来没出现这样的问题,包括使用原先的方式,用 md5($ip.$_SERVER['HTTP_USER_AGENT']) 来生成 authcode 函数里面的 $_SG['authkey']都是没有出现过登陆失败,password解密不了的问题。而这个登陆逻辑上是没有问题的,况且如果程序有错误,为何不是 100%的用户无法登录???

------------------------------------------------------




登陆失败日志的格式(记入函数是放在cp.php当中的):

2010-09-05 11:05:06[122.131.15.222]
username: xiaopeng
userid : 1068
password :
HTTP_COOKIE : lzstat_uv=3418342431107704546|715378@1358765; Kv5jT_userid=1068; Kv5jT_password=747bXLdM2hjqb4rcpJJ1ATWwu8VHc%2FgYTSO3wMvMmy2VExT%2FKw; Kv5jT_username=xiaopeng
HTTP_USER_AGENT : Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; CIBA; TheWorld)
--------------------------------------------


百思不得其解,希望高手帮我一下,里面应该有错误,还有这个COOKIE当中的“lzstat_uv”,我并没有设置这个,但是部分登录用户的COOKIE中却有他,但是有的登陆失败的用户的COOKIE值里面并没他。

这个问题已经很久了,我实在是解决不了,CSDN的各位高人,帮帮我吧.....
...全文
836 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
已经解决,应该是由于某些访问者的IP不停的变化。另外一个因素是IE内核的浏览器发送的头部标识也是经常会变。所以才导致加密后解密不了。
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 jim8590251 的回复:]

[/Quote]
广告。。。
jim8590251 2010-09-20
  • 打赏
  • 举报
回复
jim8590251 2010-09-20
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 default7 的回复:]

其实是可能的原因便是访问者的IP是动态不停的变动的。
有这样的情况。

后来还遇到了一例,查看日志发现他的IP是动态不停的变换的IP。
[/Quote]

应该是这个原因吧,很多人的IP是不停的变化的。
好奇怪啊,为什么有的人的IP是不停的变化的呢?难道是我的PHP获取IP地址有问题?不太可能啊。


//获取在线IP
function getip($format=0)
{
global $_SG;

if(empty($_SG['ip']))
{
if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'))
{
$ip = getenv('HTTP_CLIENT_IP');
}
elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'))
{
$ip = getenv('HTTP_X_FORWARDED_FOR');
}
elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown'))
{
$ip = getenv('REMOTE_ADDR');
}
elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown'))
{
$ip = $_SERVER['REMOTE_ADDR'];
}
preg_match("/[\d\.]{7,15}/", $ip, $onlineipmatches);
$_SG['ip'] = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';
}
if($format) $_SG['ip'] = ipformat($_SG['ip']);
return $_SG['ip'];
}



应该是IP的问题吧~~~~


  • 打赏
  • 举报
回复
其实是可能的原因便是访问者的IP是动态不停的变动的。
有这样的情况。

后来还遇到了一例,查看日志发现他的IP是动态不停的变换的IP。
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 klend 的回复:]

用ucenter了? 注册和登陆的具体流程是什么?
[/Quote]

没有啊,只是用到了DISCUZ 的那个authcode函数而已。
klend 2010-09-07
  • 打赏
  • 举报
回复
用ucenter了? 注册和登陆的具体流程是什么?

21,893

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧