今天咱们来学习的是 PHP 中的一个过期的扩展 Mcrypt 。在 PHP7 以前,这个扩展是随 PHP 安装包一块儿内置发布的,可是如今新版本的 PHP 中已经没有了,须要使用这个扩展的话咱们须要单独安装,而且在使用的时候也是会报出过期的警告的。因此,咱们学习使用这些函数的时候,就须要使用 @ 来抑制错误信息。固然,之因此会对这套扩展发出过期警告,是由于 PHP 更加推荐使用 OpenSSL 来处理相似的加密能力。php
Mcrypt 主要是使用的 Mcrypt 工具来进行加密操做的,因此在 CentOS 或者其它操做系统中,咱们须要安装 libmcrypt-devel 来使用这个扩展。若是 yum 中没法安装的话,直接更新 yum 源便可。git
Mcrypt 包含不少的模块和算法。算法就不用多解释了,就是用来对数据进行加密的方式。而模块,包括 CBC, OFB,CFB 和 ECB 这几种,是一系列的分组、流式加密的模式,有推荐的模块,也有安全的模块,具体的区分你们能够自行查阅相关的资料,这里咱们先看一下咱们的环境中所支持的模块和算法。github
$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);
代码比较多也较乱,咱们一块一块来看。json
首先是咱们肯定一个加密的 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://www.php.net/manual/zh/book.mcrypt.php
各自媒体平台都可搜索【硬核项目经理】