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 array_intersect比array_diff快(附详细的使用说明)
Jul 03 PHP
PHP mb_convert_encoding文字编码的转换函数介绍
Nov 10 PHP
基于php iconv函数的使用详解
Jun 09 PHP
神盾加密解密教程(一)PHP变量可用字符
May 28 PHP
浅谈php扩展imagick
Jun 02 PHP
php实现压缩多个CSS与JS文件的方法
Nov 11 PHP
php中explode的负数limit用法分析
Feb 27 PHP
PHP异常处理浅析
May 12 PHP
PHP生成json和xml类型接口数据格式
May 17 PHP
PHP模拟asp.net的StringBuilder类实现方法
Aug 08 PHP
浅析PHP中的i++与++i的区别及效率
Jun 15 PHP
基于PHP实现短信验证码接口(容联运通讯)
Sep 06 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
利用static实现表格的颜色隔行显示
2006/10/09 PHP
PHP逐行输出(ob_flush与flush的组合)
2012/02/04 PHP
PHP多线程类及用法实例
2014/12/03 PHP
php在linux下检测mysql同步状态的方法
2015/01/15 PHP
jQuery+ajax实现顶一下,踩一下效果
2010/07/17 Javascript
JQuery EasyUI 对话框的使用方法
2010/10/24 Javascript
模拟jQuery ajax服务器端与客户端通信的代码
2011/03/28 Javascript
js获取电脑分辨率的思路及操作
2013/11/22 Javascript
jquery实现的下拉和收缩效果示例
2014/08/21 Javascript
jquery实现仿新浪微博带动画效果弹出层代码(可关闭、可拖动)
2015/10/12 Javascript
Eclipse编辑jsp、js文件时卡死现象的解决办法汇总
2016/02/02 Javascript
JavaScript数据结构学习之数组、栈与队列
2017/05/02 Javascript
ZeroClipboard.js使用一个flash复制多个文本框
2017/06/19 Javascript
JavaScript动态绑定详解
2017/09/14 Javascript
Vue使用枚举类型实现HTML下拉框步骤详解
2018/02/05 Javascript
使用微信小程序开发弹出框应用实例详解
2018/10/18 Javascript
详解jQuery如何实现模糊搜索
2019/05/10 jQuery
解决LayUI数据表格复选框不居中显示的问题
2019/09/25 Javascript
[01:08]2014DOTA2展望TI 剑指西雅图LGD战队专访
2014/06/30 DOTA
[07:52]2014DOTA2 TI逗比武士游V社解说背后的故事
2014/07/10 DOTA
[57:50]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第二局
2016/03/05 DOTA
[05:37]DOTA2-DPC中国联赛 正赛 Elephant vs iG 选手采访
2021/03/11 DOTA
详解python中字典的循环遍历的两种方式
2017/02/07 Python
Python中序列的修改、散列与切片详解
2017/08/27 Python
Python数据结构之顺序表的实现代码示例
2017/11/15 Python
Python嵌套式数据结构实例浅析
2019/03/05 Python
Django rstful登陆认证并检查session是否过期代码实例
2019/08/13 Python
python GUI库图形界面开发之PyQt5布局控件QGridLayout详细使用方法与实例
2020/03/06 Python
Jupyter notebook 启动闪退问题的解决
2020/04/13 Python
用python实现名片管理系统
2020/06/18 Python
俄罗斯购买剧院和演唱会门票网站:Parter.ru
2019/11/09 全球购物
安全生产中长期规划实施方案
2014/02/21 职场文书
空气环保标语
2014/06/12 职场文书
超级礼物观后感
2015/06/15 职场文书
小学开学典礼新闻稿
2015/07/17 职场文书
MySQL慢查询的坑
2021/04/28 MySQL