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常用函数小技巧
Sep 11 PHP
PHP源码之 ext/mysql扩展部分
Jul 17 PHP
php HandlerSocket的使用
May 02 PHP
php max_execution_time执行时间问题
Jul 17 PHP
CI(CodeIgniter)框架配置
Jun 10 PHP
php+mysql查询优化简单实例
Jan 13 PHP
PHP滚动日志的代码实现
Jun 10 PHP
PHP实现批量修改文件后缀名的方法
Jul 30 PHP
实例讲解yii2.0在php命令行中运行的步骤
Dec 01 PHP
解决出现SoapFault (looks like we got no XML document)的问题
Jun 24 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
Mar 24 PHP
phpStudy vscode 搭建debug调试的教程详解
Jul 28 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中unlink()、mkdir()、rmdir()等方法的使用介绍
2012/12/21 PHP
Linux系统中设置多版本PHP共存配合Nginx服务器使用
2015/12/21 PHP
PHP中ID设置自增后不连续的原因分析及解决办法
2016/08/21 PHP
微信公众平台开发(五) 天气预报功能开发
2016/12/03 PHP
JavaScript 验证浏览器是否支持javascript的方法小结
2009/05/17 Javascript
js编码、解码函数介绍及其使用示例
2013/09/05 Javascript
用unescape反编码得出汉字示例
2014/04/24 Javascript
JS 调用微信扫一扫功能
2016/12/22 Javascript
巧用canvas
2017/01/21 Javascript
jQuery Plupload上传插件的使用
2017/04/19 jQuery
javascript实现Java中的Map对象功能的实例详解
2017/08/21 Javascript
vue 实现左右拖拽元素并且不超过他的父元素的宽度
2018/11/30 Javascript
vuex 动态注册方法 registerModule的实现
2019/07/03 Javascript
elementUI 动态生成几行几列的方法示例
2019/07/11 Javascript
Bootstrap table 实现树形表格联动选中联动取消功能
2019/09/30 Javascript
使用python统计文件行数示例分享
2014/02/21 Python
Python生成随机验证码的两种方法
2015/12/22 Python
使用Python神器对付12306变态验证码
2016/01/05 Python
python3新特性函数注释Function Annotations用法分析
2016/07/28 Python
Python批量更改文件名的实现方法
2017/10/29 Python
pytorch构建网络模型的4种方法
2018/04/13 Python
pandas 使用apply同时处理两列数据的方法
2018/04/20 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
PyTorch之图像和Tensor填充的实例
2019/08/18 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
Html5定位终极解决方案
2020/02/05 HTML / CSS
幼儿园教师国培感言
2014/02/02 职场文书
医疗纠纷协议书
2014/04/16 职场文书
项目经理任命书
2014/06/04 职场文书
纺织工程专业推荐信
2014/09/08 职场文书
2015年社区中秋节活动总结
2015/03/23 职场文书
2015年节能降耗工作总结
2015/05/22 职场文书
Python insert() / append() 用法 Leetcode实战演示
2021/03/31 Python
MySQL 百万级数据的4种查询优化方式
2021/06/07 MySQL
python绘制简单直方图(质量分布图)的方法
2022/04/21 Python
处理canvas绘制图片模糊问题
2022/05/11 Javascript