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 相关文章推荐
PHP5中的this,self和parent关键字详解教程
Mar 19 PHP
Mysql和网页显示乱码解决方法集锦
Mar 27 PHP
thinkphp模板的包含与渲染实例分析
Nov 26 PHP
PHP模板解析类实例
Jul 09 PHP
深入浅析php json 格式控制
Dec 24 PHP
PHP实现清除MySQL死连接的方法
Jul 23 PHP
总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
Sep 09 PHP
php in_array() 检查数组中是否存在某个值详解
Nov 23 PHP
PHP中单例模式与工厂模式详解
Feb 17 PHP
PHP的PDO大对象(LOBs)
Jan 27 PHP
PHP5.6读写excel表格文件操作示例
Feb 26 PHP
php转换上传word文件为PDF的方法【基于COM组件】
Jun 10 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
php5.2.0内存管理改进
2007/01/22 PHP
php 动态多文件上传
2009/01/18 PHP
PHP 作用域解析运算符(::)
2010/07/27 PHP
php判断输入是否是纯数字,英文,汉字的方法
2015/03/05 PHP
什么是PHP文件?如何打开PHP文件?
2017/06/27 PHP
PHP7引入的&quot;??&quot;和&quot;?:&quot;的区别讲解
2019/04/08 PHP
jquery使用ColorBox弹出图片组浏览层实例演示
2013/03/14 Javascript
原生js实现查找/添加/删除/指定元素的class
2013/04/12 Javascript
Jquery 点击按钮自动高亮实现原理及代码
2014/04/25 Javascript
js全选实现和判断是否有复选框选中的方法
2015/02/17 Javascript
ECMAScript6函数剩余参数(Rest Parameters)
2015/06/12 Javascript
浅析Node.js的Stream模块中的Readable对象
2015/07/29 Javascript
在其他地方你学不到的jQuery小贴士和技巧(欢迎收藏)
2016/01/20 Javascript
基于JavaScript实现 网页切出 网站title变化代码
2016/04/03 Javascript
Backbone View 之间通信的三种方式
2016/08/09 Javascript
jQuery实现的自动加载页面功能示例
2016/09/04 Javascript
JavaScript实现格式化字符串函数String.format
2016/12/16 Javascript
详解webpack-dev-server使用方法
2018/09/14 Javascript
React和Vue中监听变量变化的方法
2018/11/14 Javascript
VUE脚手架具体使用方法
2019/05/20 Javascript
Node.js在图片模板上生成二维码图片并附带底部文字说明实现详解
2019/08/07 Javascript
Element-Ui组件 NavMenu 导航菜单的具体使用
2019/10/24 Javascript
Angular如何由模板生成DOM树的方法
2019/12/23 Javascript
js实现查询商品案例
2020/07/22 Javascript
vue在响应头response中获取自定义headers操作
2020/07/24 Javascript
jQuery实现简单三级联动效果
2020/09/05 jQuery
浅谈python socket函数中,send与sendall的区别与使用方法
2017/05/09 Python
python实现求最长回文子串长度
2018/01/22 Python
Python unittest模块用法实例分析
2018/05/25 Python
匈牙利最大的健身制造商和销售商:inSPORTline
2018/10/30 全球购物
小学五年级学生评语
2014/04/22 职场文书
微笑服务演讲稿
2014/05/13 职场文书
自我检讨报告
2015/01/28 职场文书
2015年学校办公室主任工作总结
2015/07/20 职场文书
oracle删除超过N天数据脚本的方法
2022/02/28 Oracle
springboot 全局异常处理和统一响应对象的处理方式
2022/06/28 Java/Android