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 相关文章推荐
如何在PHP中使用Oracle数据库(3)
Oct 09 PHP
PHP如何得到当前页和上一页的地址?
Nov 27 PHP
php扩展ZF――Validate扩展
Jan 10 PHP
用PHP实现读取和编写XML DOM代码
Apr 07 PHP
字母顺序颠倒而单词顺序不变的php代码
Aug 08 PHP
php $_SERVER windows系统与linux系统下的区别说明
Feb 14 PHP
PHP exif扩展方法开启详解
Jul 28 PHP
php实现用于删除整个目录的递归函数
Mar 16 PHP
PHP生成树的方法
Jul 28 PHP
Yii2简单实现给表单添加验证码的方法
Jul 18 PHP
PHP SFTP实现上传下载功能
Jul 26 PHP
PHP实现通过文本文件统计页面访问量功能示例
Feb 13 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 flv视频时间获取函数
2010/06/29 PHP
php array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
2011/07/12 PHP
php获取远程图片的两种 CURL方式和sockets方式获取远程图片
2011/11/07 PHP
PHP中isset()和unset()函数的用法小结
2014/03/11 PHP
百度工程师讲PHP函数的实现原理及性能分析(三)
2015/05/13 PHP
CodeIgniter配置之database.php用法实例分析
2016/01/20 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
laravel7学习之无限级分类的最新实现方法
2020/09/30 PHP
Javascript this关键字使用分析
2008/10/21 Javascript
jquery中dom操作和事件的实例学习-表单验证
2011/11/30 Javascript
JavaScript中的原型和继承详解(图文)
2014/07/18 Javascript
js带缩略图的图片轮播效果代码分享
2015/09/14 Javascript
dedecms页面如何获取会员状态的实例代码
2016/03/15 Javascript
JS代码实现根据时间变换页面背景效果
2016/06/16 Javascript
理解Angular的providers给Http添加默认headers
2017/07/04 Javascript
JS实现图片居中悬浮效果
2017/12/25 Javascript
Angular数据绑定机制原理
2018/04/17 Javascript
vue服务端渲染操作简单入门实例分析
2019/08/28 Javascript
Vue实现将数据库中带html标签的内容输出(原始HTML(Raw HTML))
2019/10/28 Javascript
javascript设计模式 ? 适配器模式原理与应用实例分析
2020/04/13 Javascript
浅谈python中的占位符
2017/11/09 Python
使用PyInstaller将python转成可执行文件exe笔记
2018/05/26 Python
基于python的图片修复程序(实现水印去除)
2018/06/04 Python
python进阶之多线程对同一个全局变量的处理方法
2018/11/09 Python
Python实现带参数的用户验证功能装饰器示例
2018/12/14 Python
详解python 爬取12306验证码
2019/05/10 Python
python 实现音频叠加的示例
2020/10/29 Python
彻底解决Python包下载慢问题
2020/11/15 Python
html5 canvas绘制矩形和圆形的实例代码
2016/06/16 HTML / CSS
数控加工专业毕业生自荐信
2013/09/27 职场文书
《听鱼说话》教学反思
2014/02/15 职场文书
小学生评语大全
2014/04/18 职场文书
一年级小学生评语
2014/04/22 职场文书
小米11和iphone12哪个值得买?小米11对比iphone12评测
2021/04/21 数码科技
用Python selenium实现淘宝抢单机器人
2021/06/18 Python
忘记Grafana不要紧2种Grafana重置admin密码方法详细步骤
2022/04/07 Servers