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 strtotime 函数UNIX时间戳
Jan 14 PHP
php 魔术方法使用说明
Oct 20 PHP
Warning: session_destroy() : Trying to destroy uninitialized sessionq错误
Jun 16 PHP
php smarty 二级分类代码和模版循环例子
Jun 16 PHP
Zend Framework中的简单工厂模式 图文
Jul 10 PHP
PHP获取网址的顶级域名函数代码
Sep 24 PHP
PHPEXCEL 使用小记
Jan 06 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(一)
Jun 23 PHP
PHP实现支持SSL连接的SMTP邮件发送类
Mar 05 PHP
php实现源代码加密的方法
Jul 11 PHP
服务器迁移php版本不同可能诱发的问题
Dec 22 PHP
PHP面向对象程序设计重载(overloading)操作详解
Jun 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网上调查系统
2006/10/09 PHP
PHP __autoload函数(自动载入类文件)的使用方法
2012/02/04 PHP
PHP工程师VIM配置分享
2015/12/15 PHP
php结合md5实现的加密解密方法
2016/01/25 PHP
php加密之discuz内容经典加密方式实例详解
2017/02/04 PHP
用jquery ajax获取网站Alexa排名的代码
2009/12/12 Javascript
GWT中复制到剪贴板 js+flash实现复制 兼容性比较好
2010/03/07 Javascript
快速查找数组中的某个元素并返回下标示例
2013/09/03 Javascript
JS的document.all函数使用示例
2013/12/30 Javascript
10个很棒的jQuery代码片段
2015/09/24 Javascript
bootstrap网页框架的使用方法
2016/05/10 Javascript
js 判断各种数据类型的简单方法(推荐)
2016/08/29 Javascript
React快速入门教程
2017/01/17 Javascript
Vue中添加过渡效果的方法
2017/03/16 Javascript
jQuery实现下拉菜单动态添加数据点击滑出收起其他功能
2018/06/14 jQuery
在vue中使用公共过滤器filter的方法
2018/06/26 Javascript
JavaScript鼠标拖拽事件详解
2020/04/03 Javascript
用Python实现通过哈希算法检测图片重复的教程
2015/04/02 Python
Python设计模式之工厂模式简单示例
2018/01/09 Python
python 爬虫 批量获取代理ip的实例代码
2018/05/22 Python
python 正确保留多位小数的实例
2018/07/16 Python
python2与python3共存问题的解决方法
2018/09/18 Python
Python 利用scrapy爬虫通过短短50行代码下载整站短视频
2018/10/29 Python
Python使用pyshp库读取shapefile信息的方法
2018/12/29 Python
Python判断变量名是否合法的方法示例
2019/01/28 Python
使用python将excel数据导入数据库过程详解
2019/08/27 Python
10分钟理解CSS3 FlexBox弹性布局
2018/12/20 HTML / CSS
移动端HTML5 input常见问题(小结)
2020/09/28 HTML / CSS
银行财务部实习生的自我鉴定
2013/11/27 职场文书
致裁判员加油稿
2014/02/08 职场文书
领导班子整改方案和个人整改措施
2014/10/25 职场文书
Golang二维切片初始化的实现
2021/04/08 Golang
Python Pandas模块实现数据的统计分析的方法
2021/06/24 Python
Python爬虫基础之简单说一下scrapy的框架结构
2021/06/26 Python
vue项目配置sass及引入外部scss文件
2022/04/14 Vue.js
JS class语法糖的深入剖析
2022/07/07 Javascript