discuz加密解密函数使用方法和中文注释


Posted in PHP onJanuary 21, 2014
<?php
/**
 * $string 明文或密文
 * $operation 加密ENCODE或解密DECODE
 * $key 密钥
 * $expiry 密钥有效期
 */ 
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
    // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
    // 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
    // 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
    // 当此值为 0 时,则不产生随机密钥
    $ckey_length = 4;    // 密匙
    // $GLOBALS['discuz_auth_key'] 这里可以根据自己的需要修改
    $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') {
        // substr($result, 0, 10) == 0 验证数据有效性
        // substr($result, 0, 10) - time() > 0 验证数据有效性
        // substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性
        // 验证数据有效性,请看未加密明文的格式
        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));
    }
}


$a = 3water.com;
$b = authcode($a, "ENCODE", "abc123");
echo $b."<br/>";
echo authcode($b, "DECODE", "abc123");
?>
PHP 相关文章推荐
PHP 高手之路(三)
Oct 09 PHP
用PHP中的 == 运算符进行字符串比较
Nov 26 PHP
php 生成饼图 三维饼图
Sep 28 PHP
在PHP中设置、使用、删除Cookie的解决方法
May 06 PHP
php cURL和Rolling cURL并发方式比较
Oct 30 PHP
php自定义的格式化时间示例代码
Dec 05 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十二)
Jun 25 PHP
PHP中使用file_get_contents post数据代码例子
Feb 13 PHP
在Windows XP下安装Apache+MySQL+PHP环境
Feb 22 PHP
WordPress中获取指定分类及其子分类下的文章数目
Dec 31 PHP
Laravel中unique和exists验证规则的优化详解
Jan 28 PHP
php开发最强大的IDE编辑的phpstorm 2020.2配置Xdebug调试的详细教程
Aug 17 PHP
php加密算法之实现可逆加密算法和解密分享
Jan 21 #PHP
检查用户名是否已在mysql中存在的php写法
Jan 20 #PHP
php设计模式之单例模式使用示例
Jan 20 #PHP
php实现图形显示Ip地址的代码及注释
Jan 20 #PHP
php判断手机访问还是电脑访问示例分享
Jan 20 #PHP
利用中国天气预报接口实现简单天气预报
Jan 20 #PHP
php日历制作代码分享
Jan 20 #PHP
You might like
php分页函数
2006/07/08 PHP
windows服务器中检测PHP SSL是否开启以及开启SSL的方法
2014/04/25 PHP
一个php短网址的生成代码(仿微博短网址)
2014/05/07 PHP
php使用cookie保存用户登录的用户名实例
2015/01/26 PHP
浅谈php+phpStorm+xdebug配置方法
2015/09/17 PHP
动态改变div的z-index属性的简单实例
2013/08/08 Javascript
浅谈jQuery中 wrap() wrapAll() 与 wrapInner()的差异
2014/11/12 Javascript
js获取字符串最后一位方法汇总
2014/11/13 Javascript
js实现双击图片放大单击缩小的方法
2015/02/17 Javascript
JQuery包裹DOM节点的方法
2015/06/11 Javascript
js简单实现表单中点击按钮动态增加输入框数量的方法
2015/08/18 Javascript
关于Vue实现组件信息的缓存问题
2017/08/23 Javascript
node.js 用socket实现聊天的示例代码
2017/10/17 Javascript
vue router 跳转后回到顶部的实例
2018/08/31 Javascript
详解Vue.js v-for不支持IE9的解决方法
2018/12/29 Javascript
微信小程序 image组件遇到的问题
2019/05/28 Javascript
autojs 蚂蚁森林能量自动拾取即给指定好友浇水的实现方法
2020/05/03 Javascript
在react项目中使用antd的form组件,动态设置input框的值
2020/10/24 Javascript
node koa2 ssr项目搭建的方法步骤
2020/12/11 Javascript
[06:01]刀塔次级联赛top10第一期
2014/11/07 DOTA
Python入门篇之数字
2014/10/20 Python
Python使用redis pool的一种单例实现方式
2016/04/16 Python
全面了解Nginx, WSGI, Flask之间的关系
2018/01/09 Python
网易2016研发工程师编程题 奖学金(python)
2019/06/19 Python
pytorch 图像预处理之减去均值,除以方差的实例
2020/01/02 Python
Python使用Socket实现简单聊天程序
2020/02/28 Python
基于python实现MQTT发布订阅过程原理解析
2020/07/27 Python
美国餐厅用品和厨房设备批发网站:KaTom Restaurant Supply
2018/01/27 全球购物
美国狗旅行和户外用品领先供应商:kurgo
2020/08/18 全球购物
英语专业学生的自我评价
2013/12/30 职场文书
办公设备采购方案
2014/03/16 职场文书
优秀员工评优方案
2014/06/13 职场文书
2015年六一儿童节活动方案
2015/05/05 职场文书
导游词之平津战役纪念馆
2019/11/04 职场文书
分享一些Java的常用工具
2021/06/11 Java/Android
Python django中如何使用restful框架
2021/06/23 Python