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 相关文章推荐
我的论坛源代码(六)
Oct 09 PHP
thinkPHP的Html模板标签使用方法
Nov 13 PHP
浅析PHP安装扩展mcrypt以及相关依赖项(PHP安装PECL扩展的方法)
Jul 05 PHP
推荐25款php中非常有用的类库
Sep 29 PHP
php的GD库imagettftext函数解决中文乱码问题
Jan 24 PHP
用php来限制每个ip每天浏览页面数量的实现思路
Feb 24 PHP
PDO防注入原理分析以及注意事项
Feb 25 PHP
PHP调用.NET的WebService 简单实例
Mar 27 PHP
深入理解PHP内核(二)之SAPI探究
Nov 10 PHP
yii2 RBAC使用DbManager实现后台权限判断的方法
Jul 23 PHP
php利用ob_start()清除输出和选择性输出的方法
Jan 18 PHP
phpquery中文手册
Mar 18 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实现AES256加密算法实例
2014/09/22 PHP
Yii数据读取与跳转参数传递用法实例分析
2016/07/12 PHP
javascript 贪吃蛇实现代码
2008/11/22 Javascript
js 图片缩放(按比例)控制代码
2009/05/27 Javascript
js 未结束的字符串常量错误解决方法
2010/06/13 Javascript
json对象转字符串如何实现
2012/12/02 Javascript
js中传递特殊字符(+,&amp;)的方法
2014/01/16 Javascript
JS的get和set使用示例
2014/02/20 Javascript
js使用正则实现ReplaceAll全部替换的方法
2014/08/22 Javascript
详细解密jsonp跨域请求
2015/04/15 Javascript
详解Javascript模板引擎mustache.js
2016/01/20 Javascript
jQuery+CSS实现一个侧滑导航菜单代码
2016/05/09 Javascript
深入剖析javascript中的exec与match方法
2016/05/18 Javascript
jQuery ui autocomplete选择列表被Bootstrap模态窗遮挡的完美解决方法
2016/09/23 Javascript
SeaJS中use函数用法实例分析
2017/10/10 Javascript
js处理包含中文的字符串实例
2017/10/11 Javascript
详解bootstrap导航栏.nav与.navbar区别
2017/11/23 Javascript
vue移动UI框架滑动加载数据的方法
2018/03/12 Javascript
vue实现父子组件之间的通信以及兄弟组件的通信功能示例
2019/01/29 Javascript
微信小程序搭建自己的Https服务器
2019/05/02 Javascript
微信小程序实现点击卡片 翻转效果
2019/09/04 Javascript
详解vue 组件的实现原理
2020/11/12 Javascript
Python读写unicode文件的方法
2015/07/10 Python
使用Python来开发Markdown脚本扩展的实例分享
2016/03/04 Python
python傅里叶变换FFT绘制频谱图
2019/07/19 Python
python pip安装包出现:Failed building wheel for xxx错误的解决
2019/12/25 Python
pytorch实现保证每次运行使用的随机数都相同
2020/02/20 Python
汉米尔顿手表官网:Hamilton
2020/09/13 全球购物
Marlies Dekkers内衣荷兰官方网店:荷兰奢侈内衣品牌
2020/03/27 全球购物
泰国最新活动和优惠:Megatix
2020/05/07 全球购物
Java中的基本数据类型所占存储空间大小固定的吗
2012/02/15 面试题
自主招生自荐书
2013/11/29 职场文书
项目合作协议书范本
2014/04/16 职场文书
环保专项行动方案
2014/05/12 职场文书
跳蚤市场口号
2014/06/13 职场文书
小学生反邪教心得体会
2016/01/15 职场文书