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数据库连接
Oct 09 PHP
php将数据库中所有内容生成静态html文档的代码
Apr 12 PHP
PHP 缓存实现代码及详细注释
May 16 PHP
基于curl数据采集之单页面采集函数get_html的使用
Apr 28 PHP
php批量删除cookie的简单实现方法
Jan 26 PHP
PHP stream_context_create()函数的使用示例
May 12 PHP
又十个超级有用的PHP代码片段
Sep 24 PHP
基于PHP给大家讲解防刷票的一些技巧
Nov 18 PHP
CentOS 7.2 下编译安装PHP7.0.10+MySQL5.7.14+Nginx1.10.1的方法详解(mini版本)
Sep 01 PHP
Yii2框架制作RESTful风格的API快速入门教程
Nov 08 PHP
Thinkphp5 如何隐藏入口文件index.php(URL重写)
Oct 16 PHP
深入解析PHP底层机制及相关原理
Dec 11 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 mkdir()定义和用法
2009/01/14 PHP
php数组函数序列之sort() 对数组的元素值进行升序排序
2011/11/02 PHP
记录mysql性能查询过程的使用方法
2013/05/02 PHP
PHP制作用户注册系统
2015/10/23 PHP
WordPress中用于获取文章信息以及分类链接的函数用法
2015/12/18 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
php连接MSsql server的五种方法总结
2018/03/04 PHP
PHP递归的三种常用方式
2019/02/28 PHP
JavaScript中OnLoad几种使用方法
2012/12/15 Javascript
js实现单一html页面两套css切换代码
2013/04/11 Javascript
jquery中filter方法用法实例分析
2015/02/06 Javascript
老生常谈javascript变量的命名规范和注释
2016/09/29 Javascript
解析如何利用iframe标签以及js制作时钟
2016/12/08 Javascript
jQuery表格(Table)基本操作实例分析
2017/03/10 Javascript
webpack配置的最佳实践分享
2017/04/21 Javascript
AngularJS 打开新的标签页实现代码
2017/09/07 Javascript
用vue构建多页面应用的示例代码
2017/09/20 Javascript
JS获取今天是本月第几周、本月共几周、本月有多少天、是今年的第几周、是今年的第几天的示例代码
2018/12/05 Javascript
JS实现查找数组中对象的属性值是否存在示例
2019/05/24 Javascript
[03:39]2015国际邀请赛主赛事首日精彩回顾
2015/08/05 DOTA
Python中文件I/O高效操作处理的技巧分享
2017/02/04 Python
Python常见读写文件操作实例总结【文本、json、csv、pdf等】
2019/04/15 Python
如何使用python写截屏小工具
2020/09/29 Python
python 自定义异常和主动抛出异常(raise)的操作
2020/12/11 Python
PAUL HEWITT手表美国站:德国北部时尚生活配饰品牌,船锚元素
2017/11/18 全球购物
Godiva巧克力英国官网:比利时歌帝梵巧克力
2018/08/28 全球购物
LG西班牙网上商店:Tienda LG Online Es
2019/07/30 全球购物
L’Artisan Parfumeur官网:法国香水品牌
2020/08/11 全球购物
大学学年自我鉴定
2013/10/28 职场文书
《一本男孩子必读的书》教学反思
2014/02/19 职场文书
2014年最新学校运动会广播稿
2014/09/17 职场文书
办公用品质量保证书
2015/05/11 职场文书
CSS实现章节添加自增序号的方法
2021/06/23 HTML / CSS
Springboot集成阿里云OSS上传文件系统教程
2021/06/28 Java/Android
Redis三种集群模式详解
2021/10/05 Redis
Apache Hudi的多版本清理服务彻底讲解
2022/03/31 Servers