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与MySQL交互使用详解
Oct 09 PHP
Php Mssql操作简单封装支持存储过程
Dec 11 PHP
PHP无刷新上传文件实现代码
Sep 19 PHP
解析PHP计算页面执行时间的实现代码
Jun 18 PHP
如何在php中正确的使用json
Aug 06 PHP
PHP实现获取中英文首字母
Jun 19 PHP
浅谈PHP的$_SERVER[SERVER_NAME]
Feb 04 PHP
PHP 返回数组后处理方法(开户成功后弹窗提示)
Jul 03 PHP
visual studio code 调试php方法(图文详解)
Sep 15 PHP
PHP环形链表实现方法示例
Sep 15 PHP
php strftime函数的详细用法
Jun 21 PHP
php使用curl模拟多线程实现批处理功能示例
Jul 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
文件上传类
2006/10/09 PHP
改进的IP计数器
2006/10/09 PHP
PHP新手上路(十)
2006/10/09 PHP
php程序的国际化实现方法(利用gettext)
2011/08/14 PHP
利用PHP实现图片等比例放大和缩小的方法详解
2013/06/06 PHP
PHP获取当前日期所在星期(月份)的开始日期与结束日期(实现代码)
2013/06/18 PHP
PHP中fwrite与file_put_contents性能测试代码
2013/08/02 PHP
ThinkPHP单字母函数(快捷方法)使用总结
2014/07/23 PHP
php修改指定文件后缀的方法
2014/09/11 PHP
smarty自定义函数用法示例
2016/05/20 PHP
20个非常棒的Jquery实用工具 国外文章
2010/01/01 Javascript
jQuery实现数字加减效果汇总
2014/12/16 Javascript
javascript中函数作为参数调用的方法
2015/02/09 Javascript
javascript中createElement的两种创建方式
2015/05/14 Javascript
如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
2016/02/23 Javascript
js判断鼠标位置是否在某个div中的方法
2016/02/26 Javascript
jquery 动态增加,减少input表单的简单方法(必看)
2016/10/12 Javascript
微信小程序 页面传参实例详解
2016/11/16 Javascript
解决使用vue.js路由后失效的问题
2018/03/17 Javascript
vue.js打包之后可能会遇到的坑!
2018/06/03 Javascript
Vue 获取数组键名的方法
2018/06/21 Javascript
Vue环境搭建+VSCode+Win10的详细教程
2020/08/19 Javascript
基于python实现KNN分类算法
2020/04/23 Python
Python中单线程、多线程和多进程的效率对比实验实例
2019/05/14 Python
Django的用户模块与权限系统的示例代码
2019/07/24 Python
python实现简单银行管理系统
2019/10/25 Python
python实现tail -f 功能
2020/01/17 Python
Python文件读写w+和r+区别解析
2020/03/26 Python
Python通过两个dataframe用for循环求笛卡尔积
2020/04/29 Python
使用OpenCV校准鱼眼镜头的方法
2020/11/26 Python
IE10 Error.stack 让脚本调试更加方便快捷
2013/04/22 HTML / CSS
销售演讲稿范文
2014/01/08 职场文书
文化产业实施方案
2014/06/07 职场文书
二十年同学聚会致辞
2015/07/28 职场文书
python爬虫请求库httpx和parsel解析库的使用测评
2021/05/10 Python
Django+Nginx+uWSGI 定时任务的实现方法
2022/01/22 Python