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写的小东西
Dec 06 PHP
PHP学习笔记 (1) 环境配置与代码调试
Jun 19 PHP
php木马webshell扫描器代码
Jan 25 PHP
PHP文件大小格式化函数合集
Mar 10 PHP
探寻PHP脚本不报错的原因
Jun 12 PHP
Smarty局部缓存的几种方法简介
Jun 17 PHP
php实现批量压缩图片文件大小的脚本
Jul 04 PHP
PHP中SERIALIZE和JSON的序列化与反序列化操作区别分析
Oct 11 PHP
使用PHPWord生成word文档的方法详解
Jun 06 PHP
php实现登录页面的简单实例
Sep 29 PHP
解决Laravel 不能创建 migration 的问题
Oct 09 PHP
laravel框架创建授权策略实例分析
Nov 22 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
《星际争霸》各版本雷兽特点图文解析 雷兽不同形态一览
2020/03/02 星际争霸
php实例分享之mysql数据备份
2014/05/19 PHP
Win7 64位系统下PHP连接Oracle数据库
2014/08/20 PHP
PHP防盗链代码实例
2014/08/27 PHP
如何解决PHP无法实现多线程的问题
2015/09/25 PHP
Laravel框架使用monolog_mysql实现将系统日志信息保存到mysql数据库的方法
2018/08/16 PHP
laravel http 自定义公共验证和响应的方法
2019/09/29 PHP
PHP上传图片到数据库并显示的实例代码
2019/12/20 PHP
Javascript查询DBpedia小应用实例学习
2013/03/07 Javascript
解析dom中的children对象数组元素firstChild,lastChild的使用
2013/07/10 Javascript
jQuery的deferred对象详解
2014/11/12 Javascript
jQuery及JS实现循环中暂停的方法
2015/02/02 Javascript
基于BootStrap的图片轮播效果展示实例代码
2016/05/23 Javascript
在Docker快速部署Node.js应用的详细步骤
2016/09/02 Javascript
Jquery Easyui验证组件ValidateBox使用详解(20)
2016/12/18 Javascript
Vuejs 组件——props数据传递的实例代码
2017/03/07 Javascript
js鼠标跟随运动效果
2017/03/11 Javascript
JavaScript观察者模式(publish/subscribe)原理与实现方法
2017/03/30 Javascript
jquery在启动页面时,自动加载数据的实例
2018/01/22 jQuery
详解iview的checkbox多选框全选时校验问题
2019/06/10 Javascript
JS实现transform实现扇子效果
2020/01/17 Javascript
[00:36]我的中国心——Serenity vs Fnatic
2018/08/21 DOTA
Python使用回溯法子集树模板解决爬楼梯问题示例
2017/09/08 Python
利用Hyperic调用Python实现进程守护
2018/01/02 Python
python实现微信定时每天和女友发送消息
2019/04/29 Python
JupyterNotebook设置Python环境的方法步骤
2019/12/03 Python
Pycharm如何自动生成头文件注释
2020/11/14 Python
CSS3 实现图形下落动画效果
2020/11/13 HTML / CSS
韩国CJ食品专卖网:CJonmart
2016/09/11 全球购物
怎么写有吸引力的自荐信
2013/11/17 职场文书
家长学校工作方案
2014/05/07 职场文书
关于青春的演讲稿三分钟
2014/08/22 职场文书
被告代理词范文
2015/05/25 职场文书
舞出我人生观后感
2015/06/16 职场文书
2019大学生预备党员转正思想汇报
2019/06/21 职场文书
SpringCloud项目如何解决log4j2漏洞
2022/04/10 Java/Android