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 中dirname(_file_)讲解
Mar 18 PHP
PHP 飞信好友免费短信API接口开源版
Jul 22 PHP
PHP合并数组+与array_merge的区别分析
Aug 01 PHP
linux下为php添加curl扩展的方法
Jul 29 PHP
深入PHP运行环境配置的详解
Jun 04 PHP
php中使用gd库实现下载网页中所有图片
May 12 PHP
php可扩展的验证类实例(可对邮件、手机号、URL等验证)
Jul 09 PHP
php基础设计模式大全(注册树模式、工厂模式、单列模式)
Aug 31 PHP
一个实用的php验证码类
Jul 06 PHP
thinkphp分页集成实例
Jul 24 PHP
浅谈PHP中new self()和new static()的区别
Aug 11 PHP
PHP钩子与简单分发方式实例分析
Sep 04 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
探讨方法的重写(覆载)详解
2013/06/08 PHP
php使用多个进程同时控制文件读写示例
2014/02/28 PHP
php实现refresh刷新页面批量导入数据的方法
2014/12/23 PHP
php中使用gd库实现远程图片下载实例
2015/05/12 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
2019/04/03 PHP
IE php关于强制下载文件的代码
2008/08/23 Javascript
JS中confirm,alert,prompt函数使用区别分析
2010/04/01 Javascript
jquery 图片 上一张 下一张 链接效果(续篇)
2010/04/20 Javascript
prettify 代码高亮着色器google出品
2010/12/28 Javascript
jquery.post用法关于type设置问题补充
2014/01/03 Javascript
JS+CSS模拟可以无刷新显示内容的留言板实例
2015/03/03 Javascript
分享一些常用的jQuery动画事件和动画函数
2015/11/27 Javascript
jQuery qrcode生成二维码的方法
2016/04/03 Javascript
解读Bootstrap v4 sass设计
2016/05/29 Javascript
只需五句话搞定JavaScript作用域(经典)
2016/07/26 Javascript
jquery ajax后台返回list,前台用jquery遍历list的实现
2016/10/30 Javascript
vue router-link传参以及参数的使用实例
2017/11/10 Javascript
vue使用axios实现文件上传进度的实时更新详解
2017/12/20 Javascript
vue 动态修改a标签的样式的方法
2018/01/18 Javascript
使用vue-router切换页面时,获取上一页url以及当前页面url的方法
2019/05/06 Javascript
javascript实现搜索筛选功能实例代码
2020/11/12 Javascript
[38:23]完美世界DOTA2联赛循环赛 FTD vs PXG BO2第二场 11.01
2020/11/02 DOTA
Python爬虫爬取美剧网站的实现代码
2016/09/03 Python
python 读取txt中每行数据,并且保存到excel中的实例
2018/04/29 Python
flask框架实现连接sqlite3数据库的方法分析
2018/07/16 Python
使用python爬取抖音视频列表信息
2019/07/15 Python
Pandas分组与排序的实现
2019/07/23 Python
基于Python的图像数据增强Data Augmentation解析
2019/08/13 Python
使用css3 属性如何丰富图片样式(圆角 阴影 渐变)
2012/11/22 HTML / CSS
html标签之Object和EMBED标签详解
2013/07/04 HTML / CSS
详解html5页面 rem 布局适配方法
2018/01/12 HTML / CSS
Chi Chi London官网:购买连衣裙和礼服
2020/10/25 全球购物
2014学校庆三八妇女节活动总结
2014/03/01 职场文书
主要负责人任命书
2014/06/06 职场文书
监守自盗观后感
2015/06/10 职场文书
Js类的构建与继承案例详解
2021/09/15 Javascript