PHP实现基于3DES算法加密解密字符串示例


Posted in PHP onAugust 24, 2018

本文实例讲述了PHP实现基于3DES算法加密解密字符串。分享给大家供大家参考,具体如下:

3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

项目地址:https://github.com/lizhibin205/lizhibin-php-mcrypt

一、为什么要进行数据加密

数据的安全性越来越得以重视。举个例子说,保存在数据库中的用户密码并不是明文保存的,而是采用md5加密后存储,这样即使数据库被脱库,仍能保证用户密码安全。但是,md5是不可逆的,开发人员根本就不知道用户的密码到底是什么。有些时候,我们希望加密后存储的数据是可逆的,比如一些接口密钥,这样即使数据库被脱库,如果没有对应的解密方式,攻击者盗取的密钥也是不能使用的。

二、3DES加密简介

3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样:

3DES加密过程为:C=Ek3(Dk2(Ek1(M)))

3DES解密过程为:M=Dk1(EK2(Dk3(C)))

三、使用PHP实现3DES加密

1. 使用PHP实现3DES流程图

PHP实现基于3DES算法加密解密字符串示例

要使用以上的函数,在编译PHP的时候必须添加--with-mcrypt选项。

2. PHP实现3DES代码

<?php
/**
* 3DES加解密类
* @Author: 黎志斌
* @version: v1.0
* 2016年7月21日
*/
class Encrypt
{
  //加密秘钥,
  private $_key;
  private $_iv;
  public function __construct($key, $iv)
  {
    $this->_key = $key;
    $this->_iv = $iv;
  }
  /**
  * 对字符串进行3DES加密
  * @param string 要加密的字符串
  * @return mixed 加密成功返回加密后的字符串,否则返回false
  */
  public function encrypt3DES($str)
  {
    $td = mcrypt_module_open(MCRYPT_3DES, "", MCRYPT_MODE_CBC, "");
    if ($td === false) {
      return false;
    }
    //检查加密key,iv的长度是否符合算法要求
    $key = $this->fixLen($this->_key, mcrypt_enc_get_key_size($td));
    $iv = $this->fixLen($this->_iv, mcrypt_enc_get_iv_size($td));
    //加密数据长度处理
    $str = $this->strPad($str, mcrypt_enc_get_block_size($td));
    if (mcrypt_generic_init($td, $key, $iv) !== 0) {
      return false;
    }
    $result = mcrypt_generic($td, $str);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    return $result;
  }
  /**
  * 对加密的字符串进行3DES解密
  * @param string 要解密的字符串
  * @return mixed 加密成功返回加密后的字符串,否则返回false
  */
  public function decrypt3DES($str)
  {
    $td = mcrypt_module_open(MCRYPT_3DES, "", MCRYPT_MODE_CBC, "");
    if ($td === false) {
      return false;
    }
    //检查加密key,iv的长度是否符合算法要求
    $key = $this->fixLen($this->_key, mcrypt_enc_get_key_size($td));
    $iv = $this->fixLen($this->_iv, mcrypt_enc_get_iv_size($td));
    if (mcrypt_generic_init($td, $key, $iv) !== 0) {
      return false;
    }
    $result = mdecrypt_generic($td, $str);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    return $this->strUnPad($result);
  }
  /**
  * 返回适合算法长度的key,iv字符串
  * @param string $str key或iv的值
  * @param int $td_len 符合条件的key或iv长度
  * @return string 返回处理后的key或iv值
  */
  private function fixLen($str, $td_len)
  {
    $str_len = strlen($str);
    if ($str_len > $td_len) {
      return substr($str, 0, $td_len);
    } else if($str_len < $td_len) {
      return str_pad($str, $td_len, '0');
    }
    return $str;
  }
  /**
  * 返回适合算法的分组大小的字符串长度,末尾使用\0补齐
  * @param string $str 要加密的字符串
  * @param int $td_group_len 符合算法的分组长度
  * @return string 返回处理后字符串
  */
  private function strPad($str, $td_group_len)
  {
    $padding_len = $td_group_len - (strlen($str) % $td_group_len);
    return str_pad($str, strlen($str) + $padding_len, "\0");
  }
  /**
  * 返回适合算法的分组大小的字符串长度,末尾使用\0补齐
  * @param string $str 要加密的字符串
  * @return string 返回处理后字符串
  */
  private function strUnPad($str)
  {
    return rtrim($str);
  }
}
$key  = 'ABCEDFGHIJKLMNOPQ';
$iv  = '0123456789';
$des = new Encrypt($key, $iv);
$str = "abcdefghijklmnopq";
echo "source: {$str},len: ",strlen($str),"\r\n";
$e_str = $des->encrypt3DES($str);
echo "entrypt: ", $e_str, "\r\n";
$d_str = $des->decrypt3DES($e_str);
echo "dntrypt: {$d_str},len: ",strlen($d_str),"\r\n";

注意,如果要在数据库中保存加密后的数据,建议base64_encode之后再保存,以下是PHP官网上的建议:

如果你在例如 MySQL 这样的数据库中存储数据, 请注意 varchar 类型的字段会在插入数据时自动移除字符串末尾的“空格”。 由于加密后的数据可能是以空格(ASCII 32)结尾, 这种特性会导致数据损坏。 请使用 tinyblob/tinytext(或 larger)字段来存储加密数据。

PHP 相关文章推荐
php ss7.5的数据调用 (笔记)
Mar 08 PHP
PHP基础教程(php入门基础教程)一些code代码
Jan 06 PHP
php实现邮件发送并带有附件
Jan 24 PHP
ThinkPHP的截取字符串函数无法显示省略号的解决方法
Jun 25 PHP
ThinkPHP模板中判断volist循环的最后一条记录的验证方法
Jul 01 PHP
php去掉URL网址中带有PHPSESSID的配置方法
Jul 08 PHP
PHP实现根据设备类型自动跳转相应页面的方法
Jul 24 PHP
CentOS系统中PHP安装扩展的方式汇总
Apr 09 PHP
php格式文件打开的四种方法
Feb 24 PHP
Laravel框架基于中间件实现禁止未登录用户访问页面功能示例
Jan 17 PHP
TP5(thinkPHP框架)实现后台清除缓存功能示例
May 29 PHP
PHP Trait功能与用法实例分析
Jun 03 PHP
PHP与以太坊交互详解
Aug 24 #PHP
php获取微信基础接口凭证Access_token
Aug 23 #PHP
php对微信支付回调处理的方法
Aug 23 #PHP
PHP封装的验证码工具类定义与用法示例
Aug 22 #PHP
Yii2语言国际化自动配置详解
Aug 22 #PHP
PHP实现负载均衡的加权轮询方法分析
Aug 22 #PHP
PHP实现负载均衡session共享redis缓存操作示例
Aug 22 #PHP
You might like
php 生成随机验证码图片代码
2010/02/08 PHP
php写的带缓存数据功能的mysqli类
2012/09/06 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(六)
2014/06/23 PHP
php将html转成wml的WAP标记语言实例
2015/07/08 PHP
PHP获取二维数组中某一列的值集合
2015/12/25 PHP
php7基于递归实现删除空文件夹的方法示例
2017/06/15 PHP
一个JavaScript继承的实现
2006/10/24 Javascript
Script的加载方法小结
2011/01/12 Javascript
javascript表单验证 - Parsley.js使用和配置
2013/01/25 Javascript
js使用for循环查询数组中是否存在某个值
2014/08/12 Javascript
根据配置文件加载js依赖模块
2014/12/29 Javascript
JS简单实现动画弹出层效果
2015/05/05 Javascript
javascript实现动态表头及表列的展现方法
2015/07/14 Javascript
jQuery ajax应用总结
2016/06/02 Javascript
jQuery插件HighCharts绘制2D带Label的折线图效果示例【附demo源码下载】
2017/03/08 Javascript
Vue.js 表单控件操作小结
2018/03/29 Javascript
AngularJS使用$http配置对象方式与服务端交互方法
2018/08/13 Javascript
图解NodeJS实现登录注册功能
2019/09/16 NodeJs
Vue开发中常见的套路和技巧总结
2020/11/24 Vue.js
[01:13:17]Secret vs NB 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
跟老齐学Python之传说中的函数编写条规
2014/10/11 Python
Python实现统计单词出现的个数
2015/05/28 Python
基于Python Numpy的数组array和矩阵matrix详解
2018/04/04 Python
python之array赋值技巧分享
2019/11/28 Python
Python中文分词库jieba,pkusegwg性能准确度比较
2020/02/11 Python
Python3.9新特性详解
2020/10/10 Python
python调用有道智云API实现文件批量翻译
2020/10/10 Python
HTML5 Web 存储详解
2016/09/16 HTML / CSS
Nuts.com:优质散装,批发坚果、干果和巧克力等
2017/03/21 全球购物
北京某科技有限公司C# .net笔试题
2014/09/27 面试题
企业党的群众路线教育实践活动学习心得体会
2014/10/31 职场文书
2014年小学体育工作总结
2014/12/11 职场文书
党校学习党性分析材料
2014/12/19 职场文书
酒店服务员岗位职责
2015/02/09 职场文书
消夏晚会主持词
2015/06/30 职场文书
Linux系统下MySQL配置主从分离的步骤
2022/03/21 MySQL