php加密之discuz内容经典加密方式实例详解


Posted in PHP onFebruary 04, 2017

本文实例讲述了php加密之discuz内容经典加密方式。分享给大家供大家参考,具体如下:

导读:有的时候,我们希望对表里的某些敏感字段进行加密,想了好长时间没有比较好的解决方案,后台在网上查了查,放心discuz论坛的这种方案对这种情况解决的不错,特copy过来,给大家分享一下,代码如下:

header ( "Content-type:text/html;charset=UTF-8" );
echo $string='花园路888号';
echo '<hr/>加密有效期10秒,密文内容:';
// $string='1111';
$sss=authcode($string,'','',10);
echo $sss;
echo '<hr/>加密后立即解密:...';
echo authcode($sss);
sleep(6);
echo '<hr/>6秒后解密...';
$aaaa=authcode($sss);
var_dump($aaaa);
sleep(5);
echo '<hr/>再次5秒后解密...';
$aaaa=authcode($sss);
var_dump($aaaa);
/**
 *
 * @param string $string    明文或密文字符串
 * @param string $operation    DECODE表示解密,其它表示加密
 * @param string $key    密钥
 * @param int $expiry    密文有效期,0代码永不过期
 * @return string
 */
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
    // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
    $ckey_length = 4;
    // 密匙
    $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 ( '0d', $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 ) );
    }
}

以上代码运行结果:

花园路888号
加密有效期10秒,密文内容:ce9eelLd6jpd7hZJTRg+/fgg8cD9VG+1NsHvkavEKhdvhk7jcfDoQTYSAAw
加密后立即解密:...花园路888号
6秒后解密...
string'花园路888号' (length=15)
再次5秒后解密...
string'' (length=0)
PHP 相关文章推荐
PHP截取中文字符串的问题
Jul 12 PHP
PHP生成静态页面详解
Dec 05 PHP
php连接函数implode与分割explode的深入解析
Jun 26 PHP
PHP类的反射用法实例
Nov 03 PHP
php单一接口的实现方法
Jun 20 PHP
php验证码的制作思路和实现方法
Nov 12 PHP
thinkphp分页实现效果
Oct 13 PHP
PHPExcel导出2003和2007的excel文档功能示例
Jan 04 PHP
PHP微信公众号开发之微信红包实现方法分析
Jul 14 PHP
yii2.0框架使用 beforeAction 防非法登陆的方法分析
Sep 11 PHP
Docker 安装 PHP并与Nginx的部署实例讲解
Feb 27 PHP
php引用传递
Apr 01 PHP
yii2实现 &quot;上一篇,下一篇&quot; 功能的代码实例
Feb 04 #PHP
PHP正则表达式匹配替换与分割功能实例浅析
Feb 04 #PHP
/etc/php-fpm.d/www.conf 配置注意事项
Feb 04 #PHP
PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析
Feb 04 #PHP
Yii2实现多域名跨域同步登录退出
Feb 04 #PHP
PHP使用mysqli操作MySQL数据库的简单方法
Feb 04 #PHP
PHP使用preg_split()分割特殊字符(元字符等)的方法分析
Feb 04 #PHP
You might like
php中session_unset与session_destroy的区别分析
2011/06/16 PHP
ThinkPHP自动完成中使用函数与回调方法实例
2014/11/29 PHP
InnerHtml和InnerText的区别分析
2009/03/13 Javascript
javascript自执行函数之伪命名空间封装法
2010/12/25 Javascript
js页面滚动时层智能浮动定位实现(jQuery/MooTools)
2011/08/23 Javascript
Javascript 学习笔记之 对象篇(二) : 原型对象
2014/06/24 Javascript
jQuery学习笔记之基础中的基础
2015/01/19 Javascript
Javascript aop(面向切面编程)之around(环绕)分析
2015/05/01 Javascript
JS中常用的输出方式(五种)
2016/06/12 Javascript
javascript弹出窗口中增加确定取消按钮
2016/06/24 Javascript
微信小程序 配置文件详细介绍
2016/12/14 Javascript
bootstrap实现动态进度条效果
2017/03/08 Javascript
AugularJS从入门到实践(必看篇)
2017/07/10 Javascript
elementUI select组件使用及注意事项详解
2019/05/29 Javascript
vue动态子组件的两种实现方式
2019/09/01 Javascript
微信小程序左滑删除实现代码实例
2019/09/16 Javascript
vue 实现路由跳转时更改页面title
2019/11/05 Javascript
Python的Django框架下管理站点的基本方法
2015/07/17 Python
简单了解python模块概念
2018/01/11 Python
python实现m3u8格式转换为mp4视频格式
2018/02/28 Python
浅谈关于Python3中venv虚拟环境
2018/08/01 Python
python 计算平均平方误差(MSE)的实例
2019/06/29 Python
对于Python深浅拷贝的理解
2019/07/29 Python
Python对列表的操作知识点详解
2019/08/20 Python
解决python有时候import不了当前的包问题
2019/08/28 Python
python反转列表的三种方式解析
2019/11/08 Python
windows下python 3.9 Numpy scipy和matlabplot的安装教程详解
2020/11/28 Python
CSS3实现简易版的刮刮乐效果
2016/09/27 HTML / CSS
办公室前台的岗位职责
2013/12/20 职场文书
2014年自我评价
2014/01/04 职场文书
社区学习十八大感想
2014/01/22 职场文书
班长竞选演讲稿
2014/04/24 职场文书
上课不认真检讨书
2014/09/17 职场文书
县政府办公室领导班子对照检查材料思想汇报
2014/09/28 职场文书
职称评定个人总结
2015/03/05 职场文书
标准版个人借条怎么写?以及什么是借条?
2019/08/28 职场文书