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 相关文章推荐
最令PHP初学者们头痛的十四个问题
Jan 15 PHP
PHP XML备份Mysql数据库
May 27 PHP
php 图像函数大举例(非原创)
Jun 20 PHP
php判断手机访问还是电脑访问示例分享
Jan 20 PHP
Windows和Linux中php代码调试工具Xdebug的安装与配置详解
May 08 PHP
php使用正则过滤js脚本代码实例
May 10 PHP
将二维数组转为一维数组的2种方法
May 26 PHP
PHP 生成N个不重复的随机数
Jan 21 PHP
WIN8.1下搭建PHP5.6环境
Apr 29 PHP
PHP实现上传文件并存进数据库的方法
Jul 16 PHP
php数组函数array_walk用法示例
May 26 PHP
PHP实现创建以太坊钱包转账等功能
Apr 21 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
Cappuccino 卡布其诺咖啡之制作
2021/03/03 冲泡冲煮
采用PHP函数memory_get_usage获取PHP内存清耗量的方法
2011/12/06 PHP
php中unserialize返回false的解决方法
2014/09/22 PHP
CodeIgniter配置之config.php用法实例分析
2016/01/19 PHP
php使用curl并发减少后端访问时间的方法分析
2016/05/12 PHP
Yii配置与使用memcached缓存的方法
2016/07/13 PHP
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
2012/01/15 Javascript
jQuery(js)获取文字宽度(显示长度)示例代码
2013/12/31 Javascript
JS和Jquery获取和修改label的值的示例代码
2014/01/15 Javascript
JQuery弹出层示例可自定义
2014/05/19 Javascript
js防止DIV布局滚动时闪动的解决方法
2014/10/30 Javascript
js函数与php函数的区别实例浅析
2015/01/12 Javascript
将List对象列表转换成JSON格式的类实现方法
2016/07/04 Javascript
Vuex 在Vue 组件中获得Vuex 状态state的方法
2018/08/27 Javascript
JS实现方形抽奖效果
2018/08/27 Javascript
webpack 3.X学习之多页面打包的方法
2018/09/04 Javascript
express+vue+mongodb+session 实现注册登录功能
2018/12/06 Javascript
vue-cli3环境变量与分环境打包的方法示例
2019/02/18 Javascript
微信小程序实现导航栏和内容上下联动功能代码
2020/06/29 Javascript
python之wxPython菜单使用详解
2014/09/28 Python
在Linux上安装Python的Flask框架和创建第一个app实例的教程
2015/03/30 Python
Python实现多线程抓取妹子图
2015/08/08 Python
VSCode下配置python调试运行环境的方法
2018/04/06 Python
对python3新增的byte类型详解
2018/12/04 Python
Python进阶之自定义对象实现切片功能
2019/01/07 Python
如何使用django的MTV开发模式返回一个网页
2019/07/22 Python
python-视频分帧&amp;多帧合成视频实例
2019/12/10 Python
python GUI库图形界面开发之PyQt5表格控件QTableView详细使用方法与实例
2020/03/01 Python
教你使用Sublime text3搭建Python开发环境及常用插件安装另分享Sublime text3最新激活注册码
2020/11/12 Python
CSS3 :nth-child()伪类选择器实现奇偶行显示不同样式
2013/11/05 HTML / CSS
CSS3 filter(滤镜)实现网页灰色或者黑色模式的示例代码
2021/02/24 HTML / CSS
银行毕业实习自我鉴定
2013/09/19 职场文书
护理专业学生职业生涯规划范文
2014/03/11 职场文书
2015年宣传部个人工作总结
2015/05/14 职场文书
公司要求试用期员工提交“述职报告”,该怎么写?
2019/07/17 职场文书
mysql自增长id用完了该怎么办
2022/02/12 MySQL