今天我们来学习的是 PHP 中的一个过时的扩展 Mcrypt 。在 PHP7 之前,这个扩展是随 PHP 安装包一起内置发布的,但是现在新版本的 PHP 中已经没有了,需要使用这个扩展的话我们需要单独安装,并且在使用的时候也是会报出过时的警告的。所以,我们学习使用这些函数的时候,就需要使用 @ 来抑制错误信息。当然,之所以会对这套扩展发出过时警告,是因为 PHP 更加推荐使用 OpenSSL 来处理类似的加密能力。

模块和算法

Mcrypt 主要是使用的 Mcrypt 工具来进行加密操作的,所以在 CentOS 或者其它操作系统中,我们需要安装 libmcrypt-devel 来使用这个扩展。如果 yum 中无法安装的话,直接更新 yum 源即可。

Mcrypt 包含很多的模块和算法。算法就不用多解释了,就是用来对数据进行加密的方式。而模块,包括 CBC, OFB,CFB 和 ECB 这几种,是一系列的分组、流式加密的模式,有推荐的模块,也有安全的模块,具体的区分大家可以自行查阅相关的资料,这里我们先看一下我们的环境中所支持的模块和算法。

$algorithms = @mcrypt_list_algorithms();
print_r($algorithms);
// Array
// (
// [0] => cast-128
// [1] => gost
// [2] => rijndael-128
// [3] => twofish
// [4] => arcfour
// [5] => cast-256
// [6] => loki97
// [7] => rijndael-192
// [8] => saferplus
// [9] => wake
// [10] => blowfish-compat
// [11] => des
// [12] => rijndael-256
// [13] => serpent
// [14] => xtea
// [15] => blowfish
// [16] => enigma
// [17] => rc2
// [18] => tripledes
// ) $modes = @mcrypt_list_modes();
print_r($modes);
// Array
// (
// [0] => cbc
// [1] => cfb
// [2] => ctr
// [3] => ecb
// [4] => ncfb
// [5] => nofb
// [6] => ofb
// [7] => stream
// )

mcrypt_list_algorithms() 函数可以获得当前环境下所有支持的 Mcrypt 算法。而 mcrypt_list_modes() 则打印出了当前环境下所有可支持的模块。注意在某些版本的 PHP 或者某些系统中,这些内容会有所不同,在使用 Mcrypt 相关的加密能力的时候,这两项都是相互配合使用的。因此,我们有必要在需要运行 Mcrypt 的环境中预先确定好当前环境下所支持的模块和算法。

加密解密数据

$key = hash('sha256', 'secret key', true);
$input = json_encode(['id'=>1, 'data'=>'Test mcrypt!']); $td = @mcrypt_module_open('rijndael-128', '', 'cbc', '');
$iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_URANDOM);
@mcrypt_generic_init($td, $key, $iv);
$encrypted_data = @mcrypt_generic($td, $input);
@mcrypt_generic_deinit($td);
@mcrypt_module_close($td); echo $encrypted_data, PHP_EOL;
// ��I $�3���gE�ǣu(�9n�����
// p�>P $td = @mcrypt_module_open('rijndael-128', '', 'cbc', ''); @mcrypt_generic_init($td, $key, $iv);
$data = @mdecrypt_generic($td, $encrypted_data);
echo $data, PHP_EOL;
// {"id":1,"data":"Test mcrypt!"} @mcrypt_generic_deinit($td);
@mcrypt_module_close($td);

代码比较多也较乱,我们一块一块来看。

首先是我们确定一个加密的 key ,然后 input 就是我们要加密的数据。比如我们要加密一个 json 数据。这个 key 其实用字符串就可以,但我们这里也对 key 进行了一次 hash 处理,这个 hash 相关的内容在上一篇文章我们已经详细的讲解过了。

接下来就是使用 mcrypt_module_open() 打开一个加密模块句柄,这里我们使用 rijndael-128 算法和 cbc 模块。然后使用 mcrypt_create_iv() 创建一个 iv ,这个 iv 就是一个初始化向量。初始化向量的值依密码算法而不同。最基本的要求是“唯一性”,也就是说同一把密钥不重复使用同一个初始化向量。这个特性无论在分组加密或流加密中都非常重要。相信大家要是做过微信或支付宝相关的接口通信,在解密验证数据的时候一定会见过这个 iv 属性。

使用 mcrypt_generic() 生成加密结果,使用 mcrypt_generic_deinit() 结束生成初始化,最后通过 mcrypt_module_close() 关闭加密模块句柄。这样,一套 Mcrypt 加密流程就完成了。

同样的,解密流程和加密流程也是类似的,只是我们使用 mdecrypt_generic() 这个函数来进行解密就可以了。

另一种加密解密数据方式

上面的加密流程非常麻烦而且复杂,其实在 Mcrypt 中还提供了一种更简单的加密函数。

$string = 'Test MCrypt2';
$algorithm = 'rijndael-128';
$key = md5( "mypassword", true);
$iv_length = @mcrypt_get_iv_size( $algorithm, MCRYPT_MODE_CBC );
$iv = @mcrypt_create_iv( $iv_length, MCRYPT_RAND ); $encrypted = @mcrypt_encrypt( $algorithm, $key, $string, MCRYPT_MODE_CBC, $iv );
$result = @mcrypt_decrypt( $algorithm, $key, $encrypted, MCRYPT_MODE_CBC, $iv ); echo $encrypted, PHP_EOL; // \<�`�U��Uf)�Y
echo $result, PHP_EOL; // Test MCrypt2

我们依然要准备好要加密的数据,算法,key ,以及 iv 向量。然后直接使用 mcrypt_encrypt() 和 mcrypt_decrypt() 来进行加/解密就可以了,是不是方便很多。

总结

相对于 Hash 来说,Mcrypt 是可解密的对称加密形式。关于什么是对称和非对称加密,我们将在 OpenSSL 扩展的学习中详细地讲解,而 Hash 加密则是单向的加密形式,是无法通过加密后的数据反向计算获得原始数据的。它们都有不同的应用场景,不过就像 PHP 提示的那样,Mcrypt 已经是不推荐使用的扩展了,所以我们在这里只是简单的进行了加/解密的测试而已,如果有用到的小伙伴,可以根据手册进行更深入地学习。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202007/source/PHP%E7%9A%84Mcrypt%E5%8A%A0%E5%AF%86%E6%89%A9%E5%B1%95%E7%9F%A5%E8%AF%86%E4%BA%86%E8%A7%A3.php

参考文档:

https://www.php.net/manual/zh/book.mcrypt.php

https://ask.csdn.net/questions/700696

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

PHP的Mcrypt加密扩展知识了解的更多相关文章

  1. PHP mcrypt加密扩展使用总结

    在开发中,很多时候我们在前后端交互中需要对一些敏感数据进行一定的加密.PHP中有提供了mcrypt的这样一个加密扩展实现对数据的加密解密. 一.mcrypt扩展的安装 在低版本的PHP中需要在配置文件 ...

  2. php7废弃mcrypt加密,使用openssl替换

    概要: php从7.0升级到7.1废弃了一个扩展,即mcrypt扩展,虽然安装上扩展也能正常使用,但是会发出警告,告诉我们mcrypt相关方法已经被废弃,到了7.2,已经被移除,因此不建议继续使用. ...

  3. PHP的openssl加密扩展使用小结

    h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h ...

  4. iOS 数据持久化(扩展知识:模糊背景效果和密码保护功能)

    本篇随笔除了介绍 iOS 数据持久化知识之外,还贯穿了以下内容: (1)自定义 TableView,结合 block 从 ViewController 中分离出 View,轻 ViewControll ...

  5. PHP openssl加密扩展使用总结

    1.检查服务器是否已安装了openssl组件,没有则先安装好 openssl version [-a] 2.对称加密 查询openssl支持的对称加密算法 openssl_get_cipher_met ...

  6. mcrypt加密以及解密过程

    Mcrypt库支持20多种加密算法和8种加密模式,具体可以通过函数mcrypt_list_algorithms()和mcrypt_list_modes()来显示 Mcrypt扩展库可以实现加密解密功能 ...

  7. 使用php mcrypt加密解密

    数字签名:对数据和私钥进行hash运算得到消息摘要,连同消息本身一块发给客户端.数据签名强调客户端接收到的数据是来自特定服务端,服务端具有对数据不可否认性.客户端通过确认此次签名的正确性来判断拿到的消 ...

  8. 加密算法(扩展知识:Base64编码)

    在某些考虑数据安全的场景下,我们常常会用到加密解密.编码解码知识.比如把用户密码保存到数据库上,常用的方式是通过MD5或SHA1不可逆算法进行加密后密文保存. 这里主要介绍三种常用的加密算法: (1) ...

  9. PHP的OpenSSL加密扩展学习(一):对称加密

    我们已经学过不少 PHP 中加密扩展相关的内容了.而今天开始,我们要学习的则是重点中的重点,那就是 OpenSSL 加密扩展的使用.为什么说它是重点中的重点呢?一是 OpenSSL 是目前 PHP 甚 ...

随机推荐

  1. Greenplum 6安装指南(CentOS 7.X)

    一.基本概念 Greenplum是一个面向数据仓库应用的关系型数据库,因为有良好的体系结构,所以 在数据存储.高并发.高可用.线性扩展.反应速度.易用性和性价比等方面有非常 明显的优势.Greenpl ...

  2. 计算机网络:基于iptalbes的SANT和DNAT|docker的服务器发布项目--超详细一看就会

     项目说明: 模拟企业让内网服务器可以上网,同时发布内网的服务器 1.实验环 我们需要准备三台linux系统,一台作为路由器机route,其它为客户机client-1.client-2 主机改名 ho ...

  3. python关于多级包之间的引用问题

    首先得明确包和模块. 包:在一个目录下存在__init__.py,那么该目录就是一个包. 模块:一个.py文件就是一个模块. 我们可以通过from 包 import 模块来引入python文件, 也可 ...

  4. NOIP 模拟 $29\; \rm 完全背包问题$

    题解 \(by\;zj\varphi\) 一道 \(\rm dp\) 题. 现将所有种类从小到大排序,然后判断,若最小的已经大于了 \(\rm l\),那么直接就是一个裸的完全背包,因为选的总数量有限 ...

  5. kivy之CheckBox属性实操学习

    checkbox部件属性不多,本练习举例了单选,复选二种方式,并将各checkbox进行id命名,每个都绑定了相同的动作,具体大家可以看源码进行学习. 先在开发工具pycharm里新建一个项目,然后新 ...

  6. 《深入浅出vue.js》阅读笔记之数组变化侦测

    1.如何追踪变化 数组的侦测方式和对象不同,比如: this.list.push(1) 此时并不会像改变对象一样触发setter. 同理,要侦测数组的变化意味着我们在改变数组的时候得到通知,如图,我们 ...

  7. vue项目打包 部署nginx服务器 访问远程接口 本地json 跨域问题

    本文建立在你已经在windows7上已经配好了nginx的前提下进行!!! 如果没有请移步至:https://www.cnblogs.com/jack1208-rose0203/p/5739765.h ...

  8. RestTemplate post请求 Controller 接收不到值的解决方案 postForObject方法源码解析

    springboot 整合 RestTemplate 与 使用方法 RestTemplate 的 postForObject 方法有四个参数 String url => 顾名思义 这个参数是请求 ...

  9. Linux下的Shell工作原理

    Linux下的Shell工作原理 Linux系统提供给用户的最重要的系统程序是Shell命令语言解释程序.它不属于内核部分,而是在核心之外,以用户态方式运行.其基本功能是解释并执行用户打入的各种命令, ...

  10. WPF 勾选划线

    最近项目需要一个左右侧一对多的划线功能 我们先来看一下效果秃: 主要功能: 支持动态添加 支持复选 支持修改颜色 支持动态宽度 主要实现:事件的传递 应用场景:购物互选,食品搭配,角色互选 数据源 左 ...