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将向Java靠拢
Oct 09 PHP
让你的PHP同时支持GIF、png、JPEG
Oct 09 PHP
PHP5中的this,self和parent关键字详解教程
Mar 19 PHP
php 面向对象的一个例子
Apr 12 PHP
如何使用微信公众平台开发模式实现多客服
Jan 06 PHP
java微信开发之上传下载多媒体文件
Jun 24 PHP
YII2 实现多语言配置的方法分享
Jan 11 PHP
PHP中Cookie的使用详解(简单易懂)
Apr 28 PHP
Thinkphp3.2简单解决多文件上传只上传一张的问题
Sep 26 PHP
PHP实现模拟http请求的方法分析
Dec 20 PHP
PHP反射学习入门示例
Jun 14 PHP
PHPUnit + Laravel单元测试常用技能
Nov 06 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连接MySQL代码的参数说明
2008/06/07 PHP
c#中的实现php中的preg_replace
2009/12/21 PHP
phpmyadmin配置文件现在需要绝密的短密码(blowfish_secret)的2种解决方法
2014/05/07 PHP
高性能WEB开发 flush让页面分块,逐步呈现 flush让页面分块,逐步呈现
2010/06/19 Javascript
模拟jQuery ajax服务器端与客户端通信的代码
2011/03/28 Javascript
jQuery控制输入框只能输入数值的小例子
2013/03/20 Javascript
instanceof和typeof运算符的区别详解
2014/01/06 Javascript
JavaScript中的值类型转换介绍
2014/12/31 Javascript
分享一则javascript 调试技巧
2015/01/02 Javascript
JavaScript分页功能的实现方法
2015/04/25 Javascript
javascript实现别踩白块儿小游戏程序
2015/11/22 Javascript
Javascript实现Array和String互转换的方法
2015/12/21 Javascript
细数JavaScript 一个等号,两个等号,三个等号的区别
2016/10/09 Javascript
js module大战
2019/04/19 Javascript
js实现数字滚动特效
2019/12/16 Javascript
原生js拖拽实现图形伸缩效果
2020/02/10 Javascript
VUE使用axios调用后台API接口的方法
2020/08/03 Javascript
vue前端和Django后端如何查询一定时间段内的数据
2021/02/28 Vue.js
Python操作列表的常用方法分享
2014/02/13 Python
简单介绍Python中的len()函数的使用
2015/04/07 Python
Python爬虫实现使用beautifulSoup4爬取名言网功能案例
2019/09/15 Python
Django 自定义分页器的实现代码
2019/11/24 Python
Python使用Tkinter实现滚动抽奖器效果
2020/01/06 Python
Python3开发环境搭建详细教程
2020/06/18 Python
css3 transform导致子元素固定定位变成绝对定位的方法
2020/03/06 HTML / CSS
世界上最大的专业美容用品零售商:Sally Beauty
2017/07/02 全球购物
巴西最大的珠宝连锁店:Vivara
2019/04/18 全球购物
中国专业的音频分享平台:喜马拉雅
2019/05/24 全球购物
司机岗位职责
2013/11/15 职场文书
日语专业个人求职信范文
2014/02/02 职场文书
《难忘的泼水节》教学反思
2014/02/27 职场文书
百年校庆节目主持词
2014/03/27 职场文书
小学安全教育月活动总结
2014/07/07 职场文书
优秀共产党员推荐材料
2014/12/18 职场文书
如何理解Vue简单状态管理之store模式
2021/05/15 Vue.js
MySQL 数据库范式化设计理论
2022/04/22 MySQL