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 相关文章推荐
第三节 定义一个类 [3]
Oct 09 PHP
PHP中动态显示签名和ip原理
Mar 28 PHP
php 中的4种标记风格介绍
May 10 PHP
php实现统计邮件大小的方法
Aug 06 PHP
ThinkPHP的Widget扩展实例
Jun 19 PHP
php简单实现快速排序的方法
Apr 04 PHP
PHP实现简单汉字验证码
Jul 28 PHP
PHP实现合并discuz用户
Aug 05 PHP
微信支付开发动态链接Native支付
Jul 12 PHP
php中preg_replace_callback函数简单用法示例
Jul 21 PHP
PHP 读取大文件并显示的简单实例(推荐)
Aug 12 PHP
thinkPHP5分页功能实现方法分析
Oct 25 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中OO之静态关键字以及类常量的详解
2013/06/07 PHP
PHP内核探索:变量存储与类型使用说明
2014/01/30 PHP
ThinkPHP无限级分类原理实现留言与回复功能实例
2014/10/31 PHP
PHP实现事件机制实例分析
2015/06/26 PHP
[原创]IE view-source 无法查看看源码 JavaScript看网页源码
2009/07/19 Javascript
javascript 用原型继承来实现对象系统
2010/03/22 Javascript
js 禁止选择功能实现代码(兼容IE/Firefox)
2010/04/23 Javascript
js左侧三级菜单导航实例代码
2013/09/13 Javascript
jQuery ui autocomplete选择列表被Bootstrap模态窗遮挡的完美解决方法
2016/09/23 Javascript
深入理解选择框脚本[推荐]
2016/12/13 Javascript
NodeJs的fs读写删除移动监听
2017/04/28 NodeJs
Javascript中的async awai的用法
2017/05/17 Javascript
EasyUI在Panel上动态添加LinkButton按钮
2017/08/11 Javascript
微信小程序学习笔记之本地数据缓存功能详解
2019/03/29 Javascript
解决VUEX的mapState/...mapState等取值问题
2020/07/24 Javascript
Pyramid添加Middleware的方法实例
2013/11/27 Python
一个超级简单的python web程序
2014/09/11 Python
Python如何快速实现分布式任务
2017/07/06 Python
Python定时器实例代码
2017/11/01 Python
Python模拟自动存取款机的查询、存取款、修改密码等操作
2018/09/02 Python
Python实现账号密码输错三次即锁定功能简单示例
2019/03/29 Python
分析运行中的 Python 进程详细解析
2019/06/22 Python
pytorch中的上采样以及各种反操作,求逆操作详解
2020/01/03 Python
如何在django中实现分页功能
2020/04/22 Python
python求numpy中array按列非零元素的平均值案例
2020/06/08 Python
matplotlib相关系统目录获取方式小结
2021/02/03 Python
css3给背景图片加颜色遮罩的方法
2019/11/05 HTML / CSS
摩顿布朗英国官方网上商店:奢华沐浴、身体和头发护理
2016/10/29 全球购物
民警群众路线教育实践活动对照检查材料
2014/10/04 职场文书
中考百日冲刺决心书
2015/09/22 职场文书
保险公司岗前培训工作总结
2015/10/24 职场文书
2016关于学习党章的心得体会
2016/01/15 职场文书
2016党性教育学习心得体会
2016/01/21 职场文书
Redis6.0搭建集群Redis-cluster的方法
2021/05/08 Redis
如何使用PostgreSQL进行中文全文检索
2021/05/27 PostgreSQL
Redis特殊数据类型bitmap位图
2022/06/01 Redis