這次我們要學習的又是一個 Hash 加密擴充。不過這個擴充 Mhash 已經整合在 Hash 擴充中了。同時也要注意的是,這個擴充功能已經不建議使用了,我們應該直接使用 Hash 擴充中的函數來進行 Hash 加密操作。所以,我們今天仍然是以學習為目的的進行了解。關於 Hash 擴充的內容,我們可以查看先前的文章:PHP的Hash資訊摘要擴充框架 。
加密雜湊函數的使用
$hash = mhash(MHASH_MD5, "测试Mhash"); echo $hash, PHP_EOL; echo bin2hex($hash), PHP_EOL; // /�8�><�۠�P4q�j� // 2fcb38e93e3cc8dba09f503471846a9d $hash = hash('md5', "测试Mhash"); echo $hash, PHP_EOL; // 2fcb38e93e3cc8dba09f503471846a9d $hash = mhash(MHASH_MD5, "测试Mhash", 'hmac secret'); echo $hash, PHP_EOL; echo bin2hex($hash), PHP_EOL; // �k�<F�m �OM���� // b86bb83c46b76d09be4f4daf18ebfe85
從程式碼中可以看出,mhash() 函數和hash() 的使用非常像,當然,他們的作用也是一樣的。不過,mhash() 函數加密出來的直接是二進位的,我們將這個內容透過 bin2hex() 轉成 16 進位之後就可以看到和普通的 hash() 函數加密的結構是完全相同的了。
在進行 hmac 加密的時候直接在第三個參數上加入 key 就可以了。
遍歷所有支援的演算法類型
當然,就像 Hash 加密一樣,Mhash 加密也是可以選擇不同的演算法的。我們也是直接使用相關的函數就可以看到目前環境中所支援的加密演算法。
echo mhash_count(), PHP_EOL; $nr = mhash_count(); // 33 for ($i = 0; $i <= $nr; $i++) { echo sprintf("Hash:%s,块大小为: %d\n", mhash_get_hash_name($i), mhash_get_block_size($i)); } // Hash:CRC32,块大小为: 4 // Hash:MD5,块大小为: 16 // Hash:SHA1,块大小为: 20 // Hash:HAVAL256,块大小为: 32 // Hash:,块大小为: 0 // Hash:RIPEMD160,块大小为: 20 // Hash:,块大小为: 0 // Hash:TIGER,块大小为: 24 // Hash:GOST,块大小为: 32 // Hash:CRC32B,块大小为: 4 // Hash:HAVAL224,块大小为: 28 // Hash:HAVAL192,块大小为: 24 // Hash:HAVAL160,块大小为: 20 // Hash:HAVAL128,块大小为: 16 // Hash:TIGER128,块大小为: 16 // Hash:TIGER160,块大小为: 20 // Hash:MD4,块大小为: 16 // Hash:SHA256,块大小为: 32 // Hash:ADLER32,块大小为: 4 // Hash:SHA224,块大小为: 28 // Hash:SHA512,块大小为: 64 // Hash:SHA384,块大小为: 48 // Hash:WHIRLPOOL,块大小为: 64 // Hash:RIPEMD128,块大小为: 16 // Hash:RIPEMD256,块大小为: 32 // Hash:RIPEMD320,块大小为: 40 // Hash:,块大小为: 0 // Hash:SNEFRU256,块大小为: 32 // Hash:MD2,块大小为: 16 // Hash:FNV132,块大小为: 4 // Hash:FNV1A32,块大小为: 4 // Hash:FNV164,块大小为: 8 // Hash:FNV1A64,块大小为: 8 // Hash:JOAAT,块大小为: 4
在 PHP 中也提供了非常多的常數來代表這些演算法,例如在前一段程式碼中我們使用的 MHASH_MD5 。其實就是我們遍歷的這些內容在前面加上 MHASH_ 就可以了。具體支援的常數列表我們可以在官方手冊中找到,在這裡就不進行複製貼上了。
Salted S2K 演算法產生密碼摘要
另外,Mhash 也為我們提供了一個非常方便的Salted S2K 演算法可以用來方便地產生一套非常方便地密碼加密內容。
// OpenPGP 指定的 Salted S2K 算法 $hashPassword = mhash_keygen_s2k(MHASH_SHA1, '我的密码', random_bytes(2), 4); echo $hashPassword, PHP_EOL; echo bin2hex($hashPassword), PHP_EOL; // �-!= // 101ab899
當然,這個演算法也是比較安全的,有 salt 參數,而且它可以指定回傳的資料長度。它傳回的也是二進位的數據,如果需要保存標準的文字內容也需要將其轉換為 16 進位的形式。不過相對來說,我反而覺得這種直接產生二進位內容的還比較安全一些。
總結
不同的函數有不同的應用場景,但其實Mhash 已經沒有什麼特別的應用場景了,畢竟Hash 擴充中的相關函數已經完全能夠取代它的作用了,而且還更加的豐富易用。大家如果在舊的專案中見到這些函數的使用,也完全可以慢慢的透過重構替換到新的函數。
測試程式碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202007/source/PHP%E7%9A%84Mhash%E6%89%A9%E5%B1%95%E5%87%BD%E6%95%B0%E7%9A%84%E5%AD%A6%E4%B9%A0.php
推薦學習:php影片教學