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设计模式 Singleton(单例模式)
Jun 26 PHP
php 目录遍历、删除 函数的使用介绍
Apr 28 PHP
比较strtr, str_replace和preg_replace三个函数的效率
Jun 26 PHP
destoon调用discuz论坛中带图片帖子的实现方法
Aug 21 PHP
Yii中使用PHPExcel导出Excel的方法
Dec 26 PHP
ThinkPHP V2.2说明文档没有说明的那些事实例小结
Jul 01 PHP
PHP模拟asp.net的StringBuilder类实现方法
Aug 08 PHP
windows下apache搭建php开发环境
Aug 27 PHP
php实现的微信红包算法分析(非官方)
Sep 25 PHP
php编程中echo用逗号和用点号连接的区别
Mar 26 PHP
PHP正则判断一个变量是否为正整数的方法
Feb 27 PHP
yii 框架实现按天,月,年,自定义时间段统计数据的方法分析
Apr 04 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通过正则表达式下载图片到本地的实现代码
2011/09/19 PHP
Php图像处理类代码分享
2012/01/19 PHP
php中使用__autoload()自动加载未定义类的实现代码
2013/02/06 PHP
PHP实现截取中文字符串不出现?号的解决方法
2016/12/29 PHP
jquery中get,post和ajax方法的使用小结
2014/02/04 Javascript
javascript页面渲染速度测试脚本分享
2014/04/15 Javascript
jquery实现更改表格行顺序示例
2014/04/30 Javascript
javascript实现playfair和hill密码算法
2014/12/07 Javascript
JS获取地址栏参数的两种方法(简单实用)
2016/06/14 Javascript
JavaScript中闭包之浅析解读(必看篇)
2016/08/25 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
2016/09/21 Javascript
ES6中定义类和对象的方法示例
2019/07/31 Javascript
JS图片懒加载的优点及实现原理
2020/01/10 Javascript
es6函数之尾调用优化实例分析
2020/04/25 Javascript
python中的五种异常处理机制介绍
2014/09/02 Python
Python内置函数的用法实例教程
2014/09/08 Python
python实现清屏的方法
2015/04/30 Python
python基于paramiko将文件上传到服务器代码实现
2019/07/08 Python
详解Python self 参数
2019/08/30 Python
基于Django框架的权限组件rbac实例讲解
2019/08/31 Python
在Python中等距取出一个数组其中n个数的实现方式
2019/11/27 Python
pytorch 中的重要模块化接口nn.Module的使用
2020/04/02 Python
如何快速一次性卸载所有python包(第三方库)呢
2020/10/20 Python
Python的信号库Blinker用法详解
2020/12/31 Python
python中封包建立过程实例
2021/02/18 Python
如何在Canvas中添加事件的方法示例
2019/05/21 HTML / CSS
找到不普通的东西:Bonanza
2016/10/20 全球购物
Gretna Green中文官网:苏格兰格林小镇
2019/10/16 全球购物
简述数组与指针的区别
2014/01/02 面试题
网上卖盒饭创业计划书
2014/01/26 职场文书
《长城和运河》教学反思
2014/04/14 职场文书
高中班主任评语大全
2014/04/25 职场文书
保护环境倡议书范文
2014/05/13 职场文书
教师党员个人自我剖析材料
2014/09/29 职场文书
新闻稿格式范文
2015/07/18 职场文书
浅析python中特殊文件和特殊函数
2022/02/24 Python