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系统流量分析的程序
Oct 09 PHP
php xml实例 留言本
Mar 20 PHP
深入eAccelerator与memcached的区别详解
Jun 06 PHP
使用session判断用户登录用户权限(超简单)
Jun 08 PHP
探讨捕获php错误信息方法的详解
Jun 09 PHP
php字符串过滤与替换小结
Jan 26 PHP
php实现的Curl封装类Curl.class.php用法实例分析
Sep 25 PHP
php中注册器模式类用法实例分析
Nov 03 PHP
PHP中使用array函数新建一个数组
Nov 19 PHP
PHP 获取 ping 时间的实现方法
Sep 29 PHP
PHP7引入的&quot;??&quot;和&quot;?:&quot;的区别讲解
Apr 08 PHP
laravel通用化的CURD的实现
Dec 13 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
全国FM电台频率大全 - 6 辽宁省
2020/03/11 无线电
一个可以删除字符串中HTML标记的PHP函数
2006/10/09 PHP
执行、获取远程代码返回:file_get_contents 超时处理的问题详解
2013/06/25 PHP
PHP连接sql server 2005环境配置及问题解决
2014/08/08 PHP
Codeigniter发送邮件的方法
2015/03/19 PHP
php引用和拷贝的区别知识点总结
2019/09/23 PHP
基于JQuery的多标签实现代码
2012/09/19 Javascript
JavaScript 模式之工厂模式(Factory)应用介绍
2012/11/15 Javascript
jQuery点击自身以外地方关闭弹出层的简单实例
2013/12/24 Javascript
js实现网页随机切换背景图片的方法
2014/11/01 Javascript
JavaScript的jQuery库插件的简要开发指南
2015/08/12 Javascript
JavaScript的Backbone.js框架环境搭建及Hellow world示例
2016/05/07 Javascript
Bootstrap按钮下拉菜单组件详解
2016/05/10 Javascript
js对字符串进行编码的方法总结(推荐)
2016/11/10 Javascript
jQuery EasyUI 获取tabs的实例解析
2016/12/06 Javascript
jQuery封装placeholder效果实现方法,让低版本浏览器支持该效果
2017/07/08 jQuery
使用Bootstrap和Vue实现用户信息的编辑删除功能
2017/10/25 Javascript
微信小程序表单验证功能完整实例
2017/12/01 Javascript
JavaScript 有用的代码片段和 trick
2018/02/22 Javascript
D3.js的基础部分之数组的处理数组的排序和求值(v3版本)
2019/05/09 Javascript
详解可以用在VS Code中的正则表达式小技巧
2019/05/14 Javascript
vue滑动吸顶及锚点定位的示例代码
2020/05/10 Javascript
javascript前端和后台进行数据交互方法示例
2020/08/07 Javascript
Python实现单词拼写检查
2015/04/25 Python
python 与GO中操作slice,list的方式实例代码
2017/03/20 Python
Python 自动刷博客浏览量实例代码
2017/06/14 Python
Python字典操作详细介绍及字典内建方法分享
2018/01/04 Python
python使用pil库实现图片合成实例代码
2018/01/20 Python
Python图像处理之简单画板实现方法示例
2018/08/30 Python
对python调用RPC接口的实例详解
2019/01/03 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
2020/05/27 Python
Python3.5装饰器典型案例分析
2019/04/30 Python
Python类反射机制使用实例解析
2019/12/30 Python
应届大学生自荐信格式
2013/09/21 职场文书
大学同学聚会邀请函
2014/01/29 职场文书
经济管理专业求职信
2014/06/09 职场文书