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 相关文章推荐
输出控制类
Oct 09 PHP
一个改进的UBB类
Oct 09 PHP
使ecshop模板中可引用常量的实现方法
Jun 02 PHP
php数组函数序列之array_key_exists() - 查找数组键名是否存在
Oct 29 PHP
解析php取整的几种方式
Jun 25 PHP
PHP类继承 extends使用介绍
Jan 14 PHP
PHP查询大量数据内存耗尽问题的解决方法
Oct 28 PHP
PHP7多线程搭建教程
Apr 21 PHP
利用php操作memcache缓存的基础方法示例
Aug 02 PHP
thinkPHP框架实现的短信接口验证码功能示例
Jun 20 PHP
浅谈Laravel核心解读之Console内核
Dec 02 PHP
基于laravel belongsTo使用详解
Oct 18 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
一个高ai的分页函数和一个url函数
2006/10/09 PHP
探讨file_get_contents与curl效率及稳定性的分析
2013/06/06 PHP
PHPMailer发送邮件
2016/12/28 PHP
PHPExcel在linux环境下导出报500错误的解决方法
2017/01/26 PHP
PHP从尾到头打印链表实例讲解
2018/09/27 PHP
ThinkPHP3.2框架自带分页功能实现方法示例
2019/05/13 PHP
Yii框架实现对数据库的CURD操作示例
2019/09/03 PHP
jquery 动态创建元素的方式介绍及应用
2013/04/21 Javascript
Node.js静态文件服务器改进版
2016/01/10 Javascript
express文件上传中间件Multer详解
2016/10/24 Javascript
原生js实现类似fullpage的单页/全屏滚动
2017/01/22 Javascript
vue结合element-ui使用示例
2019/01/24 Javascript
Vue3.0中的monorepo管理模式的实现
2019/10/14 Javascript
[01:01:14]完美世界DOTA2联赛PWL S2 SZ vs Rebirth 第一场 11.21
2020/11/23 DOTA
[08:06]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant 选手采访
2021/03/11 DOTA
ptyhon实现sitemap生成示例
2014/03/30 Python
为python设置socket代理的方法
2015/01/14 Python
Windows8下安装Python的BeautifulSoup
2015/01/22 Python
python批量生成本地ip地址的方法
2015/03/23 Python
python使用 HTMLTestRunner.py生成测试报告
2017/10/20 Python
Pycharm 操作Django Model的简单运用方法
2018/05/23 Python
python 内置模块详解
2019/01/01 Python
浅谈Python基础—判断和循环
2019/03/22 Python
Python 实现数据结构-堆栈和队列的操作方法
2019/07/17 Python
Python 调用 Windows API COM 新法
2019/08/22 Python
Python在线和离线安装第三方库的方法
2020/10/31 Python
css3教程之倾斜页面
2014/01/27 HTML / CSS
html5的input的required使用中遇到的问题及解决方法
2018/04/24 HTML / CSS
英国最大的户外商店:Go Outdoors
2019/04/17 全球购物
什么是接口(Interface)?
2013/02/01 面试题
应聘医药代表职位求职信
2013/10/21 职场文书
行政副总岗位职责
2014/02/23 职场文书
公司廉洁自律承诺书
2014/03/27 职场文书
蟋蟀的住宅教学反思
2014/04/26 职场文书
python多次执行绘制条形图
2022/04/20 Python
Java Spring Lifecycle的使用
2022/05/06 Java/Android