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 print EOF实现方法
May 21 PHP
php操作memcache缓存方法分享
Jun 03 PHP
js代码实现微博导航栏
Jul 30 PHP
Java中final关键字详解
Aug 10 PHP
php数组函数array_key_exists()小结
Dec 10 PHP
Symfony实现行为和模板中取得request参数的方法
Mar 17 PHP
PHP strcmp()和strcasecmp()的区别实例
Nov 05 PHP
总结一些PHP中好用但又容易忽略的小知识
Jun 02 PHP
iis 7下安装laravel 5.4环境的方法教程
Jun 14 PHP
解决form中action属性后面?传递参数 获取不到的问题
Jul 21 PHP
php实现微信支付之现金红包
May 30 PHP
PHP实现考试倒计时功能代码
Apr 16 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 smarty truncate UTF8乱码问题解决办法
2014/06/13 PHP
yii操作cookie实例简介
2014/07/09 PHP
php获取一个变量的名字的方法
2014/09/05 PHP
thinkphp特殊标签用法概述
2014/11/24 PHP
PHP实现恶意DDOS攻击避免带宽占用问题方法
2015/05/27 PHP
点击下载链接 弹出页面实现代码
2009/10/01 Javascript
IE下js调试工具Companion.JS
2010/10/15 Javascript
初学js插入节点appendChild insertBefore使用方法
2011/07/04 Javascript
Javascript面向对象编程(三) 非构造函数的继承
2011/08/28 Javascript
jQuery动画效果animate和scrollTop结合使用实例
2014/04/02 Javascript
文本框只能输入数字的js代码(含小数点)
2016/07/10 Javascript
JS填写银行卡号每隔4位数字加一个空格
2016/12/19 Javascript
JavaScript Base64 作为文件上传的实例代码解析
2017/02/14 Javascript
jQuery中用on绑定事件时需注意的事项
2017/03/19 Javascript
Vue项目查看当前使用的elementUI版本的方法
2018/09/27 Javascript
koa2使用ejs和nunjucks作为模板引擎的使用
2018/11/27 Javascript
使用JavaScript解析URL的方法示例
2019/03/01 Javascript
说说Vuex的getters属性的具体用法
2019/04/15 Javascript
Vue.js+cube-ui(Scroll组件)实现类似头条效果的横向滚动导航条
2019/06/24 Javascript
vue开发简单上传图片功能
2020/06/30 Javascript
python处理PHP数组文本文件实例
2014/09/18 Python
python 捕获 shell/bash 脚本的输出结果实例
2017/01/04 Python
Python OpenCV 直方图的计算与显示的方法示例
2018/02/08 Python
pyqt5 使用label控件实时显示时间的实例
2019/06/14 Python
详解Html5原生拖拽操作
2018/01/12 HTML / CSS
把富文本的回车转为br标签
2019/08/09 HTML / CSS
快速创建 HTML5 Canvas 电信网络拓扑图的示例代码
2018/03/21 HTML / CSS
英国手机零售商:Metrofone
2019/03/18 全球购物
如何开发安全的AJAX应用
2014/03/26 面试题
4s店机修工岗位职责
2013/12/20 职场文书
小学二年级学生评语
2014/04/21 职场文书
法英专业大学生职业生涯规划范文:衡外情,量己力!
2014/09/23 职场文书
杭白菊导游词
2015/02/10 职场文书
品质保证书格式
2015/02/28 职场文书
Python IO文件管理的具体使用
2022/03/20 Python
SQL Server使用导出向导功能
2022/04/08 SQL Server