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 相关文章推荐
phpexcel导出excel的颜色和网页中的颜色显示不一致
Dec 11 PHP
探讨GDFONTPATH能否被winxp下的php支持
Jun 21 PHP
解析php根据ip查询所在地区(非常有用,赶集网就用到)
Jul 01 PHP
微信公众平台接口开发入门示例
Dec 24 PHP
php常用表单验证类用法实例
Jun 18 PHP
PHP序列化操作方法分析
Sep 28 PHP
CI框架入门之MVC简单示例
Nov 21 PHP
php7函数,声明,返回值等新特性介绍
May 25 PHP
PHP微商城开源代码实例
Mar 27 PHP
使用laravel和ajax实现整个页面无刷新的操作方法
Oct 03 PHP
tp5.1 框架查询表达式用法详解
May 25 PHP
PHP fopen中文文件名乱码问题解决方案
Oct 28 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
在任意字符集下正常显示网页的方法二(续)
2007/04/01 PHP
php smarty模版引擎中变量操作符及使用方法
2009/12/11 PHP
php中长文章分页显示实现代码
2012/09/29 PHP
PHP获取ttf格式文件字体名的方法示例
2019/03/06 PHP
Laravel 集成微信用户登录和绑定的实现
2019/12/27 PHP
点弹代码 点击页面任何位置都可以弹出页面效果代码
2012/09/17 Javascript
基于jquery实现的省市区级联无ajax
2013/09/24 Javascript
Javascript中call的两种用法实例
2013/12/13 Javascript
JavaScript给url网址进行encode编码的方法
2015/03/18 Javascript
Javascript类型转换的规则实例解析
2016/02/23 Javascript
BOM系列第二篇之定时器requestAnimationFrame
2016/08/17 Javascript
基于JavaScript Array数组方法(新手必看篇)
2016/08/20 Javascript
老生常谈ES6中的类
2017/07/31 Javascript
详解react阻止无效重渲染的多种方式
2018/12/11 Javascript
layui table去掉右侧滑动条的实现方法
2019/09/05 Javascript
在react中使用vue的状态管理的方法示例
2020/05/02 Javascript
js实现全选和全不选功能
2020/07/28 Javascript
鸿蒙系统中的 JS 开发框架
2020/09/18 Javascript
在nuxt中使用路由重定向的实例
2020/11/06 Javascript
python实现随机密码字典生成器示例
2014/04/09 Python
Python上传package到Pypi(代码简单)
2016/02/06 Python
浅析Python中的getattr(),setattr(),delattr(),hasattr()
2016/06/14 Python
Python中循环引用(import)失败的解决方法
2018/04/22 Python
PyCharm设置SSH远程调试的方法
2018/07/17 Python
Numpy中的mask的使用
2018/07/21 Python
Python类中的魔法方法之 __slots__原理解析
2019/08/26 Python
解决pycharm同一目录下无法import其他文件
2020/02/12 Python
Vs Code中8个好用的python 扩展插件
2020/10/12 Python
Marriott国际:万豪国际酒店查询预订
2017/09/25 全球购物
优秀教师工作感言
2014/02/16 职场文书
元旦联欢会主持词
2014/03/26 职场文书
法学院毕业生求职信
2014/06/25 职场文书
2015年项目经理工作总结
2015/04/30 职场文书
2016廉政教育学习心得体会
2016/01/25 职场文书
Python IO文件管理的具体使用
2022/03/20 Python
Linux中如何安装并部署Redis
2022/04/18 Servers