php用户登录之cookie信息安全分析


Posted in PHP onMay 13, 2016

本文实例讲述了php用户登录之cookie信息安全。分享给大家供大家参考,具体如下:

大家都知道用户登陆后,用户信息一般会选择保存在cookie里面,因为cookie是保存客户端,并且cookie可以在客户端用浏览器自由更改,这样将会造成用户cookie存在伪造的危险,从而可能使伪造cookie者登录任意用户的账户。

下面就说说平常一些防止用户登录cookie信息安全的方法:

一、cookie信息加密法

cookie信息加密法即用一种加密方法,加密用户信息,然后在存入cookie,这样伪造者即使得到cookie也只能在cookie有效期内对这个cookie利用,无法另外伪造cookie信息。

这里附上一个加密函数:

<?php
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
  // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
  $ckey_length = 4;
  // 密匙
  $key = md5($key ? $key : $GLOBALS['discuz_auth_key']);
  // 密匙a会参与加解密
  $keya = md5(substr($key, 0, 16));
  // 密匙b会用来做数据完整性验证
  $keyb = md5(substr($key, 16, 16));
  // 密匙c用于变化生成的密文
  $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length):
substr(md5(microtime()), -$ckey_length)) : '';
  // 参与运算的密匙
  $cryptkey = $keya.md5($keya.$keyc);
  $key_length = strlen($cryptkey);
  // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b),
//解密时会通过这个密匙验证数据完整性
  // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确
  $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 {
    // 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因
    // 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码
    return $keyc.str_replace('=', '', base64_encode($result));
  }
}
$str = 'abcdef';
$key = '3water.com';
echo $jm = authcode($str,'ENCODE',$key,0); //加密
echo "
";
echo authcode($jm ,'DECODE',$key,0); //解密
?>

这样当设置用户信息的cookie时,就无法对其进行伪造:

<?php
$user = array("uid"=-->$uid,"username"=>$username);
$user = base64_encode(serialize($user));
$user = authcode($user,'ENCODE','3water.com',0); //加密
setcookie("user",$user,time()+3600*24);
?>

二、用加密令牌对cookie进行保护

$hash = md5($uid.time());//加密令牌值
$hash_expire =time()+3600*24;//加密令牌值为一天有效期
$user = array("uid"=>$uid,"username"=>$username,"hash"=>$hash);
$user = base64_encode(serialize($user));
setcookie("user",$user,$hash_expr);

然后把$hash和$hash_expire 存入member表中hash和hash_expire对应字段中,也可以存入nosql,session

用户伪造cookie时,hash无法伪造,伪造的hash和数据库中的不一致

用户每次登陆,这个hash_expire有效期内不更新hash值,过期则更新

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP4之真OO
Oct 09 PHP
如何删除多级目录
Oct 09 PHP
投票管理程序
Oct 09 PHP
php 调用远程url的六种方法小结
Nov 02 PHP
PHP中include与require使用方法区别详解
Oct 19 PHP
kohana框架上传文件验证规则写法示例
Jul 14 PHP
php使用CURL伪造IP和来源实例详解
Jan 15 PHP
php+MySQL实现登录时验证登录名和密码是否正确
May 10 PHP
php网页版聊天软件实现代码
Aug 12 PHP
深入理解PHP类的自动载入机制
Sep 16 PHP
php查找字符串中第一个非0的位置截取
Feb 27 PHP
Laravel框架FormRequest中重写错误处理的方法
Feb 18 PHP
PHP数组函数知识汇总
May 12 #PHP
使用phpexcel类实现excel导入mysql数据库功能(实例代码)
May 12 #PHP
php similar_text()函数的定义和用法
May 12 #PHP
php使用curl并发减少后端访问时间的方法分析
May 12 #PHP
php反射类ReflectionClass用法分析
May 12 #PHP
PHP 的比较运算与逻辑运算详解
May 12 #PHP
php使用文本统计访问量的方法
May 12 #PHP
You might like
php截取utf-8中文字符串乱码的解决方法
2010/03/29 PHP
destoon供应信息title调用出公司名称的方法
2014/08/22 PHP
php获得文件夹下所有文件的递归算法的简单实例
2016/11/01 PHP
DOM相关内容速查手册
2007/02/07 Javascript
javascript里的条件判断
2007/02/27 Javascript
解决AJAX中跨域访问出现'没有权限'的错误
2008/08/20 Javascript
JavaScript初学者应注意的七个细节小结
2012/01/30 Javascript
js动态改变select选择变更option的index值示例
2014/07/10 Javascript
jQuery知识点整理
2015/01/30 Javascript
jQuery实现炫酷的鼠标轨迹特效
2015/02/01 Javascript
详解JavaScript中循环控制语句的用法
2015/06/03 Javascript
实践中学习AngularJS表单
2016/03/21 Javascript
详解JavaScript中的事件流和事件处理程序
2016/05/20 Javascript
微信小程序 wxapp地图 map详解
2016/10/31 Javascript
AngularJS实现在ng-Options加上index的解决方法
2016/11/03 Javascript
微信小程序中form 表单提交和取值实例详解
2017/04/20 Javascript
Web开发使用Angular实现用户密码强度判别的方法
2017/09/27 Javascript
Vue配合iView实现省市二级联动的示例代码
2018/07/27 Javascript
JavaScript设计模式之观察者模式实例详解
2019/01/16 Javascript
jquery+php后台实现省市区联动功能示例
2019/05/23 jQuery
python多线程之事件Event的使用详解
2018/04/27 Python
详解Python用户登录接口的方法
2019/04/17 Python
python 同时读取多个文件的例子
2019/07/16 Python
Python OpenCV视频截取并保存实现代码
2019/11/30 Python
python3中sorted函数里cmp参数改变详解
2020/03/12 Python
Python之变量类型和if判断方式
2020/05/05 Python
django 获取字段最大值,最新的记录操作
2020/08/09 Python
美国在线宠物用品商店:Entirely Pets
2017/01/01 全球购物
海信商城:海信电视、科龙空调、容声冰箱官方专卖
2017/02/07 全球购物
美国羽绒床上用品第一品牌:Pacific Coast
2018/08/25 全球购物
村委会贫困证明范本
2014/09/17 职场文书
判缓刑人员个人思想汇报
2014/10/10 职场文书
2014年管理工作总结
2014/11/22 职场文书
应届毕业生求职信范文
2015/03/19 职场文书
python 开心网和豆瓣日记爬取的小爬虫
2021/05/29 Python
Java基础——Map集合
2022/04/01 Java/Android