PHP对称加密函数实现数据的加密解密


Posted in PHP onOctober 27, 2016

项目中有一个地方用到了将用户ID加密、传至下个接点进行反解的需求。(原谅我不能透漏太多-_-!),第一个想到的就是康盛Ucenter中的一个函数,后来搜了下,在简明魔法中也找到了个简单的方法,遂整合了下,形成了自己使用的函数。

一、对称加密

发送方将明文使用密钥和算法处理成密文发送出去,接收方使用密钥和算法将密文处理成明文,发收信双方使用同一个密钥对数据进行加密和解密。

PHP对称加密函数实现数据的加密解密

因为使用同一个密钥加密、解密,所以安全性上不仅与算法有关,密钥的安全也很重要。

当然并不是密钥越复杂越好,相反密钥通常比较小的,因为虽然密钥越大,加密越强,但加密与解密的过程越慢,所以密钥的大小既要照顾到安全性,也要照顾到效率。

毕竟对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高,没了效率高这一优势,还不如直接用非对称加密。

此外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。

对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。

二、非对称加密

非对称加密相对来说,就安全很多了,它使用了一对密钥,公开密钥和私有密钥,分别用来进行加密和解密。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。

PHP对称加密函数实现数据的加密解密

最常见的非对称加密,应该就是银行系统,支付平台了。比如我们申请支付宝或者银联支付的接口时,会得到一个公钥,商城中进行支付是,用公钥将信息加密提交给平台,平台使用密钥对你的信息解密,进行支付操作等。

虽然非对称加密很安全,但是和对称加密比起来,它非常的慢,所以我们一般处理的话,大部分是用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去,回想一下你申请到的支付接口,是不是给了你一对密钥呢?^.^

三、结合使用

对称性加密速度快,发送大量数据时用比较好。非对称加密加密和解密花费时间长、速度慢,只适合对少量数据进行加密,但是,非对称加密的安全性是极高的。

扬长避短:将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。

PHP对称加密函数实现数据的加密解密

项目中使用的方法不宜透露,只在这里列出两个其他的例子吧。第一个是ucenter中的,第二个是简明魔法中看到的。

需要注意的是,由于是base64算法,加密后的字符串有可能会出现 + \ ,如果是用在url中,是不友好的,可以在外部或改下方法,正则验证递归调取下。

/**
 * 字符串加密以及解密函数
 * @param string $string 原文或者密文
 * @param string $operation 操作(ENCODE | DECODE), 默认为 DECODE
 * @param string $key 密钥
 * @param int $expiry 密文有效期, 加密时候有效, 单位 秒,0 为永久有效
 * @return string 处理后的 原文或者 经过 base64_encode 处理后的密文
 */
function _authcode ($string, $operation = 'DECODE', $key = 'Ruesin', $expiry = 0)
{
 $ckey_length = 4;
 
 $key = md5($key);
 $keya = md5(substr($key, 0, 16));
 $keyb = md5(substr($key, 16, 16));
 $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, 
   $ckey_length) : substr(md5(microtime()), - $ckey_length)) : '';
 
 $cryptkey = $keya . md5($keya . $keyc);
 $key_length = strlen($cryptkey);
 
 $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 {
  return $keyc . str_replace('=', '', base64_encode($result));
 }
}
/*********************************************************************
函数名称:encrypt
函数作用:加密解密字符串
使用方法:
加密  :encrypt('str','E','nowamagic');
解密  :encrypt('被加密过的字符串','D','nowamagic');
参数说明:
$string :需要加密解密的字符串
$operation:判断是加密还是解密:E:加密 D:解密
$key  :加密的钥匙(密匙);
*********************************************************************/
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));
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
用PHP连mysql和oracle数据库性能比较
Oct 09 PHP
从康盛产品(discuz)提取出来的模板类
Jun 28 PHP
使用PHP获取当前url路径的函数以及服务器变量
Jun 29 PHP
php获取汉字首字母的函数
Nov 07 PHP
国产PHP开发框架myqee新手快速入门教程
Jul 14 PHP
为PHP安装imagick时出现Cannot locate header file MagickWand.h错误的解决方法
Nov 03 PHP
PHP队列用法实例
Nov 05 PHP
Yii2中SqlDataProvider用法示例
Sep 22 PHP
php头像上传预览实例代码
May 02 PHP
PHP针对伪静态的注入总结【附asp与Python相关代码】
Aug 01 PHP
Thinkphp开发--集成极光推送
Sep 15 PHP
php快速导入大量数据的实例方法
Sep 23 PHP
PHP下的浮点运算不准的解决方法
Oct 27 #PHP
php函数mkdir实现递归创建层级目录
Oct 27 #PHP
PHP实现递归目录的5种方法
Oct 27 #PHP
PHP读取大文件的几种方法介绍
Oct 27 #PHP
php array_multisort 对数组进行排序详解及实例代码
Oct 27 #PHP
PHP中的密码加密的解决方案总结
Oct 26 #PHP
php 解析xml 的四种方法详细介绍
Oct 26 #PHP
You might like
PHP的宝库目录--PEAR
2006/10/09 PHP
Yii2超好用的日期和时间组件(值得收藏)
2016/05/05 PHP
PHP单例模式详解及实例代码
2016/12/21 PHP
js兼容的placeholder属性详解
2013/08/18 Javascript
JS阻止用户多次提交示例代码
2014/03/26 Javascript
AngularJS中取消对HTML片段转义的方法例子
2015/01/04 Javascript
基于JavaScript制作霓虹灯文字 代码 特效
2015/09/01 Javascript
jQuery无刷新切换主题皮肤实例讲解
2015/10/21 Javascript
js获取当前日期时间及其它日期操作汇总
2016/03/08 Javascript
js不间断滚动的简单实现
2016/06/03 Javascript
jquery中用函数来设置css样式
2016/12/22 Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
2017/01/06 Javascript
简单谈谈React中的路由系统
2017/07/25 Javascript
vue2.0+vue-dplayer实现hls播放的示例
2018/03/02 Javascript
jQuery 实现倒计时天,时,分,秒功能
2018/07/31 jQuery
代码分析vue中如何配置less
2018/09/28 Javascript
vue设置导航栏、侧边栏为公共页面的例子
2019/11/01 Javascript
详解vue-template-admin三级路由无法缓存的解决方案
2020/03/10 Javascript
Python多线程编程(五):死锁的形成
2015/04/05 Python
Python线程指南详细介绍
2017/01/05 Python
python学习笔记之列表(list)与元组(tuple)详解
2017/11/23 Python
python实现将汉字保存成文本的方法
2018/11/16 Python
Python中使用pypdf2合并、分割、加密pdf文件的代码详解
2019/05/21 Python
python判断文件夹内是否存在指定后缀文件的实例
2019/06/10 Python
在Pycharm中调试Django项目程序的操作方法
2019/07/17 Python
程序员的七夕用30行代码让Python化身表白神器
2019/08/07 Python
Python基础之字符串操作常用函数集合
2020/02/09 Python
python 解压、复制、删除 文件的实例代码
2020/02/26 Python
Python标准库shutil模块使用方法解析
2020/03/10 Python
Java软件工程师综合面试题笔试题
2013/09/08 面试题
2014年计算机专业个人自我评价
2014/01/19 职场文书
文明家庭事迹材料
2014/12/20 职场文书
2016社区平安家庭事迹材料
2016/02/26 职场文书
中秋节英文祝福语句(14句)
2019/09/11 职场文书
在NumPy中深拷贝和浅拷贝相关操作的定义和背后的原理
2022/04/14 Python
解决springboot druid数据库连接失败后一直重连的方法
2022/04/19 Java/Android