php加密解密函数authcode的用法详细解析


Posted in PHP onOctober 28, 2013

核心提示:康盛的 authcode 函数可以说对中国的PHP界作出了重大贡献。包括康盛自己的产品,以及大部分中国使用PHP的公司都用这个函数进行加密,authcode 是使用异或运算进行加密和解密。
 
康盛的 authcode 函数可以说对中国的PHP界作出了重大贡献。包括康盛自己的产品,以及大部分中国使用PHP的公司都用这个函数进行加密,authcode 是使用异或运算进行加密和解密。
  
原理如下,假如:
 
加密
 
明文:1010 1001
 
密匙:1110 0011
 
密文:0100 1010
 
得出密文0100 1010,解密之需和密匙异或下就可以了
 
解密
 
密文:0100 1010
 
密匙:1110 0011
 
明文:1010 1001
 
并没有什么高深的算法,密匙重要性很高,所以,关键在于怎么生成密匙。
 
那我们一起看下康盛的authcode怎么做的吧

// 参数解释  
 // $string: 明文 或 密文  
 // $operation:DECODE表示解密,其它表示加密  
 // $key: 密匙  
 // $expiry:密文有效期  
 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));  
   }  
 }
PHP 相关文章推荐
第六节--访问属性和方法
Nov 16 PHP
ajax 的post方法实例(带循环)
Jul 04 PHP
PHP实现单例模式最安全的做法
Jun 13 PHP
php curl 获取https请求的2种方法
Apr 27 PHP
帝国cms目录结构分享
Jul 06 PHP
php无序树实现方法
Jul 28 PHP
php获取远程文件的内容和大小
Nov 03 PHP
PHP的PDO操作简单示例
Mar 30 PHP
PHP文件操作实例总结
Sep 27 PHP
PHP文件操作详解
Dec 30 PHP
php分页查询mysql结果的base64处理方法示例
May 18 PHP
docker-compose部署php项目实例详解
Jul 30 PHP
php 模拟post_验证页面的返回状态(实例讲解)
Oct 28 #PHP
php操作mysqli(示例代码)
Oct 28 #PHP
php session_start()出错原因分析及解决方法
Oct 28 #PHP
php 强制下载文件实现代码
Oct 28 #PHP
php获取qq用户昵称和在线状态(实例分析)
Oct 27 #PHP
php获取数组长度的方法(有实例)
Oct 27 #PHP
使用淘宝IP库获取用户ip地理位置
Oct 27 #PHP
You might like
PHP 数据结构 算法 三元组 Triplet
2011/07/02 PHP
php实现微信公众平台账号自定义菜单类
2014/12/02 PHP
php获取远程文件的内容和大小
2015/11/03 PHP
phpStudy访问速度慢和启动失败的解决办法
2015/11/19 PHP
thinkphp中AJAX返回ajaxReturn()方法分析
2016/12/06 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
自写的利用PDO对mysql数据库增删改查操作类
2018/02/19 PHP
Javascript 自适应高度的Tab选项卡
2011/04/05 Javascript
DIV始终居中的js代码
2014/02/17 Javascript
node.js中的events.emitter.once方法使用说明
2014/12/10 Javascript
JS仿iGoogle自定义首页模块拖拽特效的方法
2015/02/13 Javascript
jQuery实现的经典竖向伸缩菜单效果代码
2015/09/24 Javascript
javascript判断图片是否加载完成的方法推荐
2016/05/13 Javascript
JavaScript中setter和getter方法介绍
2016/07/11 Javascript
js实现开启密码大写提示
2016/12/21 Javascript
Nodejs搭建wss服务器教程
2017/05/24 NodeJs
vue+vant-UI框架实现购物车的复选框全选和反选功能
2019/11/05 Javascript
vue fetch中的.then()的正确使用方法
2020/04/17 Javascript
JavaScript进阶(三)闭包原理与用法详解
2020/05/09 Javascript
python实现监控linux性能及进程消耗性能的方法
2014/07/25 Python
Python引用(import)文件夹下的py文件的方法
2014/08/26 Python
python使用super()出现错误解决办法
2017/08/14 Python
Python基于matplotlib实现绘制三维图形功能示例
2018/01/18 Python
对pandas中iloc,loc取数据差别及按条件取值的方法详解
2018/11/06 Python
在Pandas中给多层索引降级的方法
2018/11/16 Python
Python Django简单实现session登录注销过程详解
2019/08/06 Python
pycharm工具连接mysql数据库失败问题
2020/04/01 Python
python在一个范围内取随机数的简单实例
2020/08/16 Python
Myprotein加拿大官网:欧洲第一的运动营养品牌
2018/01/06 全球购物
Pedro官网:新加坡时尚品牌
2019/08/27 全球购物
.TTL是什么?有什么用处,通常那些工具会用到它?(ping? traceroute? ifconfig? netstat?)
2016/05/09 面试题
领导干部作风建设总结
2014/10/23 职场文书
2014年实习期工作总结
2014/11/27 职场文书
第一军规观后感
2015/06/12 职场文书
React + Threejs + Swiper 实现全景图效果的完整代码
2021/06/28 Javascript
SQL bool盲注和时间盲注详解
2022/07/23 SQL Server