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 中的一些经验积累
Oct 09 PHP
BBS(php &amp; mysql)完整版(七)
Oct 09 PHP
再次研究下cache_lite
Feb 14 PHP
PHP中ADODB类详解
Mar 25 PHP
php+jquery编码方面的一些心得(utf-8 gb2312)
Oct 12 PHP
php表单提交问题的解决方法
Apr 12 PHP
用PHP提取中英文词语以及数字的首字母的方法介绍
Apr 23 PHP
Yii结合CKEditor实现图片上传功能
Jun 13 PHP
百度实时推送api接口应用示例
Oct 21 PHP
php采用ajax数据提交post与post常见方法总结
Nov 10 PHP
Yii中特殊行为ActionFilter的使用方法示例
Oct 18 PHP
如何用PHP实现分布算法之一致性哈希算法
May 26 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中return的用法实例分析
2015/02/28 PHP
PHP PDOStatement::closeCursor讲解
2019/01/30 PHP
ThinkPHP框架整合微信支付之JSAPI模式图文详解
2019/04/09 PHP
零基础搭建Node.js、Express、Ejs、Mongodb服务器及应用开发入门
2014/12/20 Javascript
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
2015/03/31 Javascript
深入探究使JavaScript动画流畅的一些方法
2015/06/30 Javascript
nodejs爬虫抓取数据乱码问题总结
2015/07/03 NodeJs
JavaScript 链式结构序列化详解
2016/09/30 Javascript
微信小程序 后台https域名绑定和免费的https证书申请详解
2016/11/10 Javascript
Bootstrap列表组学习使用
2017/02/09 Javascript
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
2017/04/13 Javascript
JS中关于正则的巧妙操作
2017/08/31 Javascript
Bootstrap modal只加载一次数据的解决办法(推荐)
2017/11/24 Javascript
详解js正则表达式验证时间格式xxxx-xx-xx形式
2018/02/09 Javascript
在vue中使用echarts图表实例代码详解
2018/10/22 Javascript
bootstrapValidator表单校验、更改状态、新增、移除校验字段的实例代码
2020/05/19 Javascript
[01:23:24]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第三场 2月7日
2021/03/11 DOTA
Python中声明只包含一个元素的元组数据方法
2014/08/25 Python
Python算法应用实战之队列详解
2017/02/04 Python
python中requests库session对象的妙用详解
2017/10/30 Python
python Opencv将图片转为字符画
2021/02/19 Python
python pandas 对series和dataframe的重置索引reindex方法
2018/06/07 Python
Python 创建新文件时避免覆盖已有的同名文件的解决方法
2018/11/16 Python
pygame游戏之旅 按钮上添加文字的方法
2018/11/21 Python
python SQLAlchemy 中的Engine详解
2019/07/04 Python
django实现日志按日期分割
2020/05/21 Python
如何利用python web框架做文件流下载的实现示例
2020/06/02 Python
Artist Guitars新西兰:乐器在线商店
2017/09/17 全球购物
澳大利亚巧克力花束和礼品网站:Tastebuds
2019/03/15 全球购物
小学优秀班集体申报材料
2014/05/25 职场文书
群众路线查摆问题及整改措施
2014/10/10 职场文书
德能勤绩廉个人总结
2015/02/14 职场文书
求职意向书范本
2015/05/11 职场文书
开学第一周日记(三篇范文)
2019/08/23 职场文书
SpringBoot实现quartz定时任务可视化管理功能
2021/08/30 Java/Android