煮酒听雨
首页
PHP
MYSQL
WEB
Linux
关于本站
登陆
注册
PHP加密解密算法(Discuz!经典代码)
编辑时间:2017-09-11
编辑:忘尘
阅读:987
简述:authcode()并不是PHP的内置函数,是Discuz!开发的使用异或运算进行加密和解密的函数,Discuz!所有产品都是用这个函数。Discuz!或者其他程序整合UCenter的同步登录中authcode()就扮演者重要的角色。在同步登录(从项目登录到UCenter)的过程中,authcode()把用户的登录信息进行加密,因为没有加密的数据在传递过程中容易被截取,这样会暴露了用户的信息,authcode()的作用就是给传递的数据提供加密保护作用。在数据到达终端(UCenter)时authcode()再把加密的数据进行反向解密,还原数据。 ###原理如下,假如: ####加密 明文:1010 1001 密匙:1110 0011 密文:0100 1010 ####解密 密文:0100 1010 密匙:1110 0011 明文:1010 1001 ####示例代码 ```php /** * [authcode 字符串加解密] * @author [忘尘] * @param $string 明文 或 密文 * @param string $operation DECODE表示解密,其它表示加密 * @param string $key 密匙 * @param int $expiry 密文有效期 * @return bool|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('%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)); } } ```
来说两句吧
提交评论
最新评论
我的标签
函数
面试
REDIS
LNMP
验证
时间
JS
LINUX
CPA
常量
MYSQL
备份
微信
文件
压缩
优化
SVN
PHP
集合
数组
HTML
收藏
NGINX
配置
日志
性能
加密
下载
FORM
WEB
样式
SQL
表单
配置,面试,REDIS
编码
ARRAY
替换
截取
密码
版本
进程
定时
测试
事务
数据
权限
安全
防火墙
索引
设计模式
安全,面试
缓存
热文排行
LNMP状态管理命令
navicat for mysql 导入xlsx,
(置顶)开发中常用功能知识点笔记
(置顶)收藏优秀分享文章集合
PHP加密解密算法(Discuz!经典代码)
PHP 获取数组第一个元素或最后一个值
Nginx配置 nginx.conf 文件中常用配
MySQL错误日志 [Warning] IP ad
Redis持久化:快照(RDB)和AOF简解
浅析SQLmap
随机文章
友情链接
官方手册
thinkphp
php扩展
Linux命令
lnmp
PHP中文网
鸟哥Linux私房
Nginx中文文档
json格式化
Redis手册
composer中文文档
CentOS下载
流程图
VPN代理
菜鸟网
奇淼教程
首页
PHP
MYSQL
WEB
Linux
关于本站
登陆
注册