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 相关文章推荐
php5.2.0内存管理改进
Jan 22 PHP
PHP 向右侧拉菜单实现代码,测试使用中
Nov 03 PHP
最新用php获取谷歌PR值算法,附上php查询PR值代码示例
Dec 25 PHP
PHP去掉从word直接粘贴过来的没有用格式的函数
Oct 29 PHP
关于PHP二进制流 逐bit的低位在前算法(详解)
Jun 13 PHP
php5.5中类级别的常量使用介绍
Oct 02 PHP
php不用正则验证真假身份证
Nov 06 PHP
Linux中用PHP判断程序运行状态的2个方法
May 04 PHP
PHP+swoole实现简单多人在线聊天群发
Jan 19 PHP
PHP将二维数组某一个字段相同的数组合并起来的方法
Feb 26 PHP
PHP实现可自定义样式的分页类
Mar 29 PHP
php操作xml并将其插入数据库的实现方法
Sep 08 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
用Socket发送电子邮件
2006/10/09 PHP
php中debug_backtrace、debug_print_backtrace和匿名函数用法实例
2014/12/01 PHP
Symfony2中被遗弃的getRequest()方法分析
2016/03/17 PHP
php rmdir使用递归函数删除非空目录实例详解
2016/10/20 PHP
PHP第三方登录―QQ登录实现方法
2017/02/06 PHP
tbody元素支持嵌套的注意方法
2007/03/24 Javascript
js类中获取外部函数名的方法
2007/08/19 Javascript
JavaScript 比较时间大小的代码
2010/04/24 Javascript
Javascript的并行运算实现代码
2010/11/19 Javascript
如何实现修改密码时密码框显示保存到cookie的密码
2013/12/10 Javascript
详解js闭包
2014/09/02 Javascript
jquery取子节点及当前节点属性值的方法
2014/09/09 Javascript
JQuery异步加载PartialView的方法
2016/06/07 Javascript
Bootstrap实现弹性搜索框
2016/07/11 Javascript
jquery siblings获取同辈元素用法实例分析
2016/07/25 Javascript
JS点击缩略图整屏居中放大图片效果
2017/07/04 Javascript
Vue2 SSR渲染根据不同页面修改 meta
2017/11/20 Javascript
es6基础学习之解构赋值
2018/12/10 Javascript
JS如何实现动态添加的元素绑定事件
2019/11/12 Javascript
JavaScript实现简单随机点名器
2019/11/21 Javascript
JS实现页面数据懒加载
2020/02/13 Javascript
Vue实现手机扫描二维码预览页面效果
2020/05/28 Javascript
解决VUE mounted 钩子函数执行时 img 未加载导致页面布局的问题
2020/07/27 Javascript
在Python中测试访问同一数据的竞争条件的方法
2015/04/23 Python
Python中print函数简单使用总结
2019/08/05 Python
美国生日蛋糕店:Bake Me A Wish!
2017/02/08 全球购物
英国汽车座椅和婴儿车购物网站:Uber Kids
2017/04/19 全球购物
Tarte Cosmetics官网:美国最受欢迎的化妆品公司之一
2017/08/24 全球购物
英国电器零售商:PRC Direct
2018/06/21 全球购物
学习优秀党员杨宗兴先进事迹材料思想汇报
2014/09/14 职场文书
公安交警个人对照检查材料思想汇报
2014/10/01 职场文书
公司周年庆典标语
2014/10/07 职场文书
卡特教练观后感
2015/06/08 职场文书
民政局未婚证明
2015/06/15 职场文书
CSS实现两列布局的N种方法
2021/08/02 HTML / CSS
零基础学java之带参数以及返回值的方法
2022/04/10 Java/Android