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 相关文章推荐
DISCUZ 分页代码
Jan 02 PHP
PHP实时显示输出
Oct 02 PHP
php实现mysql同步的实现方法
Oct 21 PHP
第二章 PHP入门基础之php代码写法
Dec 30 PHP
php取整函数ceil,floo,round的用法及介绍
Aug 31 PHP
php延迟静态绑定实例分析
Feb 08 PHP
PHP中余数、取余的妙用
Jun 29 PHP
PHP常用工具类大全附全部代码下载
Dec 07 PHP
PHP查询分页的实现代码
Jun 09 PHP
使用php自动备份数据库表的实现方法
Jul 28 PHP
Laravel框架FormRequest中重写错误处理的方法
Feb 18 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
Dec 20 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
二次元帅气男生排行榜,只想悄悄收藏系列
2020/03/04 日漫
PHP的curl实现get,post和cookie(实例介绍)
2013/06/17 PHP
PHP的一个完美GIF等比缩放类,附带去除缩放黑背景
2014/04/01 PHP
PHP版微信公众平台红包API
2015/04/02 PHP
PHP最常用的正则表达式
2017/02/13 PHP
phpinfo无法显示的原因及解决办法
2019/02/15 PHP
ThinkPhP+Apache+PHPstorm整合框架流程图解
2020/11/23 PHP
向fckeditor编辑器插入指定代码的方法
2007/05/25 Javascript
JS函数实现动态添加CSS样式表文件
2012/12/15 Javascript
有关javascript的性能优化 (repaint和reflow)
2013/04/12 Javascript
jquery打开直接跳到网页最下面、最低端实现代码
2013/04/22 Javascript
关于Javascript作用域链的八点总结
2013/12/06 Javascript
js中回调函数的学习笔记
2014/07/31 Javascript
Javascript中的五种数据类型详解
2014/12/26 Javascript
js实现有时间限制消失的图片方法
2015/02/27 Javascript
jquery实现右键菜单插件
2015/03/29 Javascript
Struts2+jquery.form.js实现图片与文件上传的方法
2016/05/05 Javascript
jQuery简单实现中间浮窗效果
2016/09/04 Javascript
react-router JS 控制路由跳转实例
2017/06/15 Javascript
AngularJs每天学习之总体介绍
2017/08/07 Javascript
浅谈jquery fullpage 插件增加头部和版权的方法
2018/03/20 jQuery
当vue路由变化时,改变导航栏的样式方法
2018/08/22 Javascript
微信小程序如何实现radio单选框单击打勾和取消
2020/01/21 Javascript
js实现数字跳动到指定数字
2020/08/25 Javascript
[02:15]2014DOTA2国际邀请赛 专访LGD.lin小兔子是大腿
2014/07/14 DOTA
[03:20]2015国际邀请赛全明星表演赛
2015/08/08 DOTA
用ReactJS和Python的Flask框架编写留言板的代码示例
2015/12/19 Python
OpenCV+face++实现实时人脸识别解锁功能
2019/08/28 Python
Restful_framework视图组件代码实例解析
2020/11/17 Python
创业大赛策划书
2014/03/01 职场文书
《画风》教学反思
2014/04/16 职场文书
2014大学班主任工作总结
2014/11/08 职场文书
先进单位申报材料
2014/12/25 职场文书
JS实现简单控制视频播放倍速的实例代码
2021/04/18 Javascript
你真的了解redis为什么要提供pipeline功能
2021/06/22 Redis
Win11如何查看显卡型号 Win11查看显卡型号的方法
2022/08/14 数码科技