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 相关文章推荐
分页显示Oracle数据库记录的类之二
Oct 09 PHP
PHP 开发环境配置(测试开发环境)
Apr 28 PHP
php visitFile()遍历指定文件夹函数
Aug 21 PHP
mongo Table类文件 获取MongoCursor(游标)的实现方法分析
Jul 01 PHP
PHP中开启gzip压缩的2种方法
Jan 31 PHP
php通过修改header强制图片下载的方法
Mar 24 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
Dec 24 PHP
php实现的debug log日志操作类实例
Jul 12 PHP
CI框架封装的常用图像处理方法(缩略图,水印,旋转,上传等)
Nov 22 PHP
使用PHPWord生成word文档的方法详解
Jun 06 PHP
laravel 自定义常量的两种方案
Oct 14 PHP
laravel5.6框架操作数据curd写法(查询构建器)实例分析
Jan 26 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整数取余返回负数的相关解决方法
2014/05/15 PHP
php文件缓存方法总结
2016/03/16 PHP
PHP实用小技巧之调用录像的方法
2019/12/05 PHP
网页自动跳转代码收集
2009/09/27 Javascript
javascript 全选与全取消功能的实现代码
2012/12/23 Javascript
解决IE6的PNG透明JS插件使用介绍
2013/04/17 Javascript
JavaScript实现简单的时钟实例代码
2013/11/23 Javascript
javascript校验价格合法性实例(必须输入2位小数)
2014/05/05 Javascript
JS中getYear()和getFullYear()区别分析
2014/07/04 Javascript
深入探讨javascript中的数据类型
2015/03/04 Javascript
12个超实用的JQuery代码片段
2015/11/02 Javascript
JavaScript代码实现左右上下自动晃动自动移动
2016/04/08 Javascript
用jQuery向div中添加Html文本内容的简单实现
2016/07/13 Javascript
很酷的星级评分系统原生JS实现
2016/08/25 Javascript
jQuery获取Table某列的值(推荐)
2017/03/03 Javascript
Node.js 实现简单的接口服务器的实例代码
2017/05/23 Javascript
jQuery动态添加元素无法触发绑定事件的解决方法分析
2018/01/02 jQuery
小程序实现留言板
2018/11/02 Javascript
vue2.0 解决抽取公用js的问题
2020/07/31 Javascript
解决vant框架做H5时踩过的坑(下拉刷新、上拉加载等)
2020/11/11 Javascript
十条建议帮你提高Python编程效率
2016/02/16 Python
Django压缩静态文件的实现方法详析
2018/08/26 Python
pytorch实现保证每次运行使用的随机数都相同
2020/02/20 Python
基于django micro搭建网站实现加水印功能
2020/05/22 Python
HTML5 canvas基本绘图之图形组合
2016/06/27 HTML / CSS
德国运动鞋网上商店:Afew Store
2018/01/05 全球购物
竞争性谈判邀请书
2014/02/06 职场文书
公务员平时考核实施方案
2014/03/11 职场文书
中餐厅经理岗位职责
2014/04/11 职场文书
法学自荐信
2014/06/20 职场文书
夫妻双方自愿离婚协议书
2014/10/24 职场文书
中学推普周活动总结
2015/05/07 职场文书
本地通过nginx配置反向代理的全过程记录
2021/03/31 Servers
台积电称即便经济低迷也没有降价的计划
2022/04/21 数码科技
小喇叭开始广播了! 四十多年前珍贵老照片
2022/05/09 无线电
Python实现聚类K-means算法详解
2022/07/15 Python