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巧获服务器端信息
Dec 06 PHP
Windows PHP5和Apache的安装与配置
Jun 08 PHP
ubuntu10.04配置 nginx+php-fpm模式的详解
Jun 03 PHP
解析PHP中的内存管理,PHP动态分配和释放内存
Jun 28 PHP
php禁止某ip或ip地址段访问的方法
Feb 25 PHP
php实现mysql数据库分表分段备份
Jun 18 PHP
WordPress开发中用于获取近期文章的PHP函数使用解析
Jan 05 PHP
功能强大的php分页函数
Jul 20 PHP
php连接微软MSSQL(sql server)完全攻略
Nov 27 PHP
php封装的page分页类完整实例代码
Feb 01 PHP
php7 图形用户界面GUI 开发示例
Feb 22 PHP
PHP与Web页面的交互示例详解一
Aug 04 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函数ip2long转换IP时数值太大产生负数的解决方法
2013/06/06 PHP
PHP ignore_user_abort函数详细介绍和使用实例
2014/07/15 PHP
PHP+jquery+ajax实现即时聊天功能实例
2014/12/23 PHP
php实现俄罗斯乘法实例
2015/03/07 PHP
学习YUI.Ext 第三天
2007/03/10 Javascript
jQuery 页面 Mask实现代码
2010/01/09 Javascript
用jquery与css打造个性化的单选框和复选框
2010/10/20 Javascript
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
javascript使用正则表达式实现去掉空格之后的字符
2015/02/15 Javascript
JS数组去掉重复数据只保留一条的实现代码
2016/08/11 Javascript
javascript 将共享属性迁移到原型中去的实现方法
2016/08/31 Javascript
Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发
2016/08/31 Javascript
nodejs 图解express+supervisor+ejs的用法(推荐)
2017/09/08 NodeJs
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
基于Vue制作组织架构树组件
2017/12/06 Javascript
在微信小程序中渲染HTML内容的方法示例
2018/09/28 Javascript
vue最简单的前后端交互示例详解
2018/10/11 Javascript
JQuery获取元素尺寸、位置及页面滚动事件应用示例
2019/05/14 jQuery
nodejs简单抓包工具使用详解
2019/08/23 NodeJs
React组件设计模式之组合组件应用实例分析
2020/04/29 Javascript
JS图片懒加载技术实现过程解析
2020/07/27 Javascript
python 图片验证码代码
2008/12/07 Python
Python线程指南详细介绍
2017/01/05 Python
在pycharm中python切换解释器失败的解决方法
2018/10/29 Python
Python实现合并excel表格的方法分析
2019/04/13 Python
Python tkinter实现简单加法计算器代码实例
2020/05/13 Python
美国顶级防滑鞋:Shoes For Crews
2017/03/27 全球购物
远程Wi-Fi宠物监控相机:Petcube
2017/04/26 全球购物
介绍一下SQL Server的全文索引
2013/08/15 面试题
委托书的写法
2014/09/16 职场文书
2014年网管工作总结
2014/12/11 职场文书
公务员考察材料范文
2014/12/23 职场文书
诚信承诺书
2015/01/19 职场文书
跟班学习心得体会(共6篇)
2016/01/23 职场文书
关于战胜挫折的名言警句大全!
2019/07/05 职场文书
微信小程序 根据不同用户切换不同TabBar
2022/04/21 Javascript