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下将XML转换为数组
Jan 01 PHP
PHP调用Twitter的RSS的实现代码
Mar 10 PHP
谷歌音乐搜索栏的提示功能php修正代码
May 09 PHP
php开发过程中关于继承的使用方法分享
Jun 17 PHP
win7+apache+php+mysql环境配置操作详解
Jun 10 PHP
php实现统计邮件大小的方法
Aug 06 PHP
PHP获取指定函数定义在哪个文件中以及其所在的行号实例
May 08 PHP
PHP和javascript常用正则表达式及用法实例
Jul 01 PHP
php实现SAE上使用storage上传与下载文件的方法
Jun 29 PHP
PHP实现的redis主从数据库状态检测功能示例
Jul 20 PHP
php使用curl下载指定大小的文件实例代码
Sep 30 PHP
详解php协程知识点
Sep 21 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
ThinkPHP模板自定义标签使用方法
2014/06/26 PHP
jquery插件jbox使用iframe关闭问题
2009/02/09 Javascript
再谈javascript面向对象编程
2012/03/18 Javascript
javascript实现倒计时并弹窗提示特效
2015/06/05 Javascript
jQuery下拉美化搜索表单效果代码分享
2015/08/25 Javascript
javascript中alert()与console.log()的区别
2015/08/26 Javascript
javascript创建对象的几种模式介绍
2016/05/06 Javascript
JavaScript接口的实现三种方式(推荐)
2016/06/14 Javascript
js a标签点击事件
2017/03/30 Javascript
zTree获取当前节点的下一级子节点数实例
2017/09/05 Javascript
vue mint-ui学习笔记之picker的使用
2017/10/11 Javascript
TypeScript中的方法重载详解
2019/04/12 Javascript
vue+mock.js实现前后端分离
2019/07/24 Javascript
jQuery实现简易QQ聊天框
2020/02/10 jQuery
python 合并文件的具体实例
2013/08/08 Python
python中二维阵列的变换实例
2014/10/09 Python
跟老齐学Python之网站的结构
2014/10/24 Python
CentOS6.5设置Django开发环境
2016/10/13 Python
Python实现识别手写数字 Python图片读入与处理
2020/03/23 Python
python OpenCV学习笔记实现二维直方图
2018/02/08 Python
对Python 简单串口收发GUI界面的实例详解
2019/06/12 Python
python实现简单聊天室功能 可以私聊
2019/07/12 Python
python实现各种插值法(数值分析)
2019/07/30 Python
浅谈Python type的使用
2019/11/19 Python
python kafka 多线程消费者&amp;手动提交实例
2019/12/21 Python
python enumerate内置函数用法总结
2020/01/07 Python
Python使用socketServer包搭建简易服务器过程详解
2020/06/12 Python
python3 中使用urllib问题以及urllib详解
2020/08/03 Python
pycharm 实现光标快速移动到括号外或行尾的操作
2021/02/05 Python
伦敦香水公司:The London Perfume Company
2019/11/13 全球购物
校园十大歌手策划书
2014/02/01 职场文书
婚前保证书
2014/04/29 职场文书
今冬明春火灾防控工作方案
2014/05/29 职场文书
2015小学语文教师个人工作总结
2015/05/20 职场文书
三严三实·严以律己心得体会
2016/01/13 职场文书
掌握这项技巧,一年阅读300本书不是梦
2019/09/12 职场文书