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 相关文章推荐
第4章 数据处理-php正则表达式-郑阿奇(续)
Jul 04 PHP
php Calender(日历)代码分享
Jan 03 PHP
php实现excel中rank函数功能的方法
Jan 20 PHP
使用URL传输SESSION信息
Jul 14 PHP
php需登录的文件上传管理系统
Mar 21 PHP
php实现给二维数组中所有一维数组添加值的方法
Feb 04 PHP
php封装json通信接口详解及实例
Mar 07 PHP
通过php动态传数据到highcharts
Apr 05 PHP
PHP Cli 模式设置进程名称的方法
Jun 12 PHP
php输出控制函数和输出函数生成静态页面
Jun 27 PHP
Yii 框架控制器创建使用及控制器响应操作示例
Oct 14 PHP
TP5框架使用QueryList采集框架爬小说操作示例
Mar 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 异步执行方法,模拟多线程的应用分析
2013/06/03 PHP
php程序员应具有的7种能力小结
2014/11/27 PHP
PHP实现git部署的方法教程
2017/12/19 PHP
JavaScript 编程引入命名空间的方法与代码
2007/08/13 Javascript
JQuery的一些小应用收集
2010/03/27 Javascript
Extjs入门之动态加载树代码
2010/04/09 Javascript
JavaScript实用技巧(一)
2010/08/16 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
2010/11/11 Javascript
JS、jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例分享
2014/04/11 Javascript
Bootstrap每天必学之导航
2015/11/26 Javascript
AngularJs html compiler详解及示例代码
2016/09/01 Javascript
IntersectionObserver实现图片懒加载的示例
2017/09/29 Javascript
vue组件之Alert的实现代码
2017/10/17 Javascript
Vue异步加载about组件
2017/10/31 Javascript
详解Vue Elememt-UI构建管理后台
2018/02/27 Javascript
vue-cli webpack配置文件分析
2019/05/20 Javascript
vuex actions异步修改状态的实例详解
2019/11/06 Javascript
vue组件开发之slider组件使用详解
2020/08/21 Javascript
尝试使用Python多线程抓取代理服务器IP地址的示例
2015/11/09 Python
python实现简单购物商城
2016/05/21 Python
Python实现优先级队列结构的方法详解
2016/06/02 Python
浅谈python对象数据的读写权限
2016/09/12 Python
python中计算一个列表中连续相同的元素个数方法
2018/06/29 Python
使用urllib库的urlretrieve()方法下载网络文件到本地的方法
2018/12/19 Python
Pyinstaller打包.py生成.exe的方法和报错总结
2019/04/02 Python
ZABBIX3.2使用python脚本实现监控报表的方法
2019/07/02 Python
Pycharm最新激活码2019(推荐)
2019/12/31 Python
python文件操作seek()偏移量,读取指正到指定位置操作
2020/07/05 Python
python获取整个网页源码的方法
2020/08/03 Python
CSS3截取字符串实例代码【推荐】
2018/06/07 HTML / CSS
阿迪达斯丹麦官网:adidas丹麦
2016/10/01 全球购物
岗位职责定义及内容
2013/11/08 职场文书
社会实践单位意见
2015/06/05 职场文书
JS继承最简单的理解方式
2021/03/31 Javascript
JavaWeb Servlet实现网页登录功能
2021/07/04 Java/Android
Java练习之潜艇小游戏的实现
2022/03/16 Java/Android