今天我們來學習的是 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 = https://www.cnblogs.com/zyblog-coder/p/@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 = https://www.cnblogs.com/zyblog-coder/p/@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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/285569.html
標籤:PHP
上一篇:PHP的Hash資訊摘要擴展框架
下一篇:Git 使用技巧
