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 mysql分页实例代码
Apr 10 PHP
ajax+php打造进度条代码[readyState各状态说明]
Apr 12 PHP
PHP的简易冒泡法代码分享
Aug 28 PHP
thinkphp实现图片上传功能分享
Mar 04 PHP
php+xml结合Ajax实现点赞功能完整实例
Jan 30 PHP
实例讲解PHP设计模式编程中的简单工厂模式
Feb 29 PHP
php实现base64图片上传方式实例代码
Feb 22 PHP
yii2 resetful 授权验证详解
May 18 PHP
PHP中关键字interface和implements详解
Jun 14 PHP
利用Laravel生成Gravatar头像地址的优雅方法
Dec 30 PHP
PHP手机短信验证码实现流程详解
May 17 PHP
详解no input file specified 三种解决方法
Nov 29 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获取网址的顶级域名函数代码
2012/09/24 PHP
php foreach正序倒序输出示例代码
2014/07/01 PHP
php 参数过滤、数据过滤详解
2015/10/26 PHP
TP5框架页面跳转样式操作示例
2020/04/05 PHP
实现png图片和png背景透明(支持多浏览器)的方法
2009/09/08 Javascript
input输入框的自动匹配(原生代码)
2013/03/19 Javascript
关于JavaScript与HTML的交互事件
2013/04/12 Javascript
JS和jquery获取各种屏幕的宽度和高度的代码
2013/08/02 Javascript
js Select下拉列表框进行多选、移除、交换内容的具体实现方法
2013/08/13 Javascript
js实现鼠标悬停图片上时滚动文字说明的方法
2015/02/17 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
2020/03/30 Javascript
AngularJS实现元素显示和隐藏的几个案例
2015/12/09 Javascript
javascript类型系统 Array对象学习笔记
2016/01/09 Javascript
使用vue.js开发时一些注意事项
2016/04/27 Javascript
JavaScript使用链式方法封装jQuery中CSS()方法示例
2017/04/07 jQuery
vue之数据交互实例代码
2017/06/20 Javascript
解决vue build打包之后首页白屏的问题
2018/03/06 Javascript
JavaScript原型对象原理与应用分析
2018/12/27 Javascript
layui原生表单验证的实例
2019/09/09 Javascript
改变layer confirm弹窗按钮的颜色方法
2019/09/12 Javascript
vue 微信扫码登录(自定义样式)
2020/01/06 Javascript
js实现div色块拖动录制
2020/01/16 Javascript
express异步函数异常捕获示例详解
2020/11/30 Javascript
python模拟Django框架实例
2016/05/17 Python
Python数据抓取爬虫代理防封IP方法
2018/12/23 Python
Python 利用切片从列表中取出一部分使用的方法
2019/02/01 Python
Python计算公交发车时间的完整代码
2020/02/12 Python
python能做哪方面的工作
2020/06/15 Python
运动会入场词200字
2014/02/15 职场文书
同事打架检讨书
2015/05/06 职场文书
2015年乡镇工会工作总结
2015/05/19 职场文书
2015年卫生监督工作总结
2015/05/21 职场文书
2016年感恩教师节活动总结
2016/04/01 职场文书
曾国藩励志经典名言37句,蕴含哲理
2019/10/14 职场文书
使用@Value值注入及配置文件组件扫描
2021/07/09 Java/Android
新的CSS 伪类函数 :is() 和 :where()示例详解
2022/08/05 HTML / CSS