2个比较经典的PHP加密解密函数分享


Posted in PHP onJuly 01, 2014

项目中有时我们需要使用PHP将特定的信息进行加密,也就是通过加密算法生成一个加密字符串,这个加密后的字符串可以通过解密算法进行解密,便于程序对解密后的信息进行处理。
最常见的应用在用户登录以及一些API数据交换的场景。

笔者收录了一些比较经典的PHP加密解密函数代码,分享给大家。加密解密原理一般都是通过一定的加密解密算法,将密钥加入到算法中,最终得到加密解密结果。
1、非常给力的authcode加密函数,Discuz!经典代码(带详解):

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') {  

        // 验证数据有效性,请看未加密明文的格式   

        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));   

    }   

}

函数authcode($string, $operation, $key, $expiry)中的$string:字符串,明文或密文;$operation:DECODE表示解密,其它表示加密;$key:密匙;$expiry:密文有效期。

用法:

$str = 'abcdef'; 

$key = 'www.helloweba.com'; 

echo authcode($str,'ENCODE',$key,0); //加密 

$str = '56f4yER1DI2WTzWMqsfPpS9hwyoJnFP2MpC8SOhRrxO7BOk'; 

echo authcode($str,'DECODE',$key,0); //解密

2、加解密函数encrypt():

function encrypt($string,$operation,$key=''){ 

    $key=md5($key); 

    $key_length=strlen($key); 

      $string=$operation=='D'?base64_decode($string):substr(md5($string.$key),0,8).$string; 

    $string_length=strlen($string); 

    $rndkey=$box=array(); 

    $result=''; 

    for($i=0;$i<=255;$i++){ 

           $rndkey[$i]=ord($key[$i%$key_length]); 

        $box[$i]=$i; 

    } 

    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=='D'){ 

        if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8)){ 

            return substr($result,8); 

        }else{ 

            return''; 

        } 

    }else{ 

        return str_replace('=','',base64_encode($result)); 

    } 

}

函数encrypt($string,$operation,$key)中$string:需要加密解密的字符串;$operation:判断是加密还是解密,E表示加密,D表示解密;$key:密匙。
用法:

$str = 'abc'; 

$key = 'www.helloweba.com'; 

$token = encrypt($str, 'E', $key); 

echo '加密:'.encrypt($str, 'E', $key); 

echo '解密:'.encrypt($str, 'D', $key);
PHP 相关文章推荐
PHP 和 MySQL 开发的 8 个技巧
Oct 09 PHP
通过ODBC连接的SQL SERVER实例
Oct 09 PHP
Banner程序
Oct 09 PHP
PHP版自动生成文章摘要
Jul 23 PHP
php 随机数的产生、页面跳转、件读写、文件重命名、switch语句
Aug 07 PHP
不要轻信 PHP_SELF的安全问题
Sep 05 PHP
用PHP书写安全的脚本代码
Feb 05 PHP
PHP可变函数学习小结
Nov 29 PHP
Laravel手动分页实现方法详解
Oct 09 PHP
PHP串行化与反串行化实例分析
Dec 27 PHP
php使用include 和require引入文件的区别
Feb 16 PHP
thinkphp5实现微信扫码支付
Dec 23 PHP
PHP实现生成唯一编号(36进制的不重复编号)
Jul 01 #PHP
ThinkPHP使用smarty模板引擎的方法
Jul 01 #PHP
PHP使用GIFEncoder类处理gif图片实例
Jul 01 #PHP
ThinkPHP模板IF标签用法详解
Jul 01 #PHP
PHP使用GIFEncoder类生成gif动态滚动字幕
Jul 01 #PHP
PHP使用GIFEncoder类生成的GIF动态图片验证码
Jul 01 #PHP
ThinkPHP模板范围判断输出In标签与Range标签用法详解
Jun 30 #PHP
You might like
无数据库的详细域名查询程序PHP版(3)
2006/10/09 PHP
php中常用字符串处理代码片段整理
2011/11/07 PHP
Mac版PhpStorm之XAMPP整合apache服务器配置的图文教程详解
2016/10/13 PHP
PHP实现限制IP访问的方法
2017/04/20 PHP
PHP封装XML和JSON格式数据接口操作示例
2019/03/06 PHP
在JavaScript中,为什么要尽可能使用局部变量?
2009/04/06 Javascript
JavaScript 捕获窗口关闭事件
2009/07/26 Javascript
下拉列表选择项的选中在不同浏览器中的兼容性问题探讨
2013/09/18 Javascript
javascript中文本框中输入法切换的问题
2013/12/10 Javascript
JS中产生标识符方式的演变
2015/06/12 Javascript
KnockoutJs快速入门教程
2016/05/16 Javascript
js判断数组key是否存在(不用循环)的简单实例
2016/08/03 Javascript
jQuery图片前后对比插件beforeAfter用法示例【附demo源码下载】
2016/09/20 Javascript
整理关于Bootstrap过渡动画的慕课笔记
2017/03/29 Javascript
详解jquery选择器的原理
2017/08/01 jQuery
vue-cli创建的项目,配置多页面的实现方法
2018/03/15 Javascript
微信小程序实现自动定位功能
2018/10/31 Javascript
原生JS实现手动轮播图效果实例代码
2018/11/22 Javascript
小程序日历控件使用方法详解
2018/12/29 Javascript
vue-socket.io跨域问题有效解决方法
2020/02/11 Javascript
浅谈javascript如何获取文件后缀名
2020/08/07 Javascript
微信小程序:报错(in promise) MiniProgramError
2020/10/30 Javascript
[05:10]2014DOTA2国际邀请赛 通往胜利之匙赛场探秘之旅
2014/07/18 DOTA
[00:23]魔方之谜解锁款式
2018/12/20 DOTA
浅谈Python中列表生成式和生成器的区别
2015/08/03 Python
python如何实现远程控制电脑(结合微信)
2015/12/21 Python
Python实现网络端口转发和重定向的方法
2016/09/19 Python
Python计算两个日期相差天数的方法示例
2017/05/23 Python
python读取目录下所有的jpg文件,并显示第一张图片的示例
2019/06/13 Python
python实现吃苹果小游戏
2020/03/21 Python
如何让IE9以下版本(ie6/7/8)认识html5元素
2013/04/01 HTML / CSS
美国时尚女装在线:Missguided
2016/12/03 全球购物
最新创业融资计划书
2014/01/19 职场文书
工地安全检查制度
2014/02/04 职场文书
2016年高校自主招生自荐信范文
2015/03/24 职场文书
遇事可以测出您的见识与格局
2019/09/16 职场文书