首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 實現 mhash 兼容方案:擴展缺失時的 HMAC-MD5 純 PHP 替代實現

     編輯:PHP 相關知識

PHP 實現 mhash 兼容方案:擴展缺失時的 HMAC-MD5 純 PHP 替代實現

調用 mhash() 報 Call to undefined function mhash(),通常是未安裝 php_mhash.dll 及依賴的 libmhash.dll。除編譯安裝擴展外,可採用純 PHP 實現的 hmac_md5() 兼容現有調用代碼,零依賴、即插即用。

方案一:安裝擴展(推薦生產環境)

  1. 下載 php_mhash.dll 對應 PHP 版本/TS/NTS。
  2. 下載 libmhash.dll 放入系統 PATH(如 C:\Windows\System32 或 PHP 目錄)。
  3. Apache httpd.conf 添加:LoadFile "C:/php/libmhash.dll"。
  4. php.ini 啟用:extension=php_mhash.dll。
  5. 重啟 Apache/驗證 php -m | grep mhash。

方案二:純 PHP 兼容函數(快速修復/無擴展權限環境)

<?php
/**
 * HMAC-MD5 兼容 mhash(MHASH_MD5, $data, $key)
 * @param string $key  密鑰
 * @param string $data 數據
 * @return string 十六進制哈希字符串
 */
function hmac_md5($key, $data) {
    // 若擴展存在,優先使用原生(性能更好)
    if (extension_loaded('mhash')) {
        return bin2hex(mhash(MHASH_MD5, $data, $key));
    }

    $b = 64; // MD5 分組長度(字節)
    // 密鑰過長先哈希縮短
    if (strlen($key) > $b) {
        $key = pack('H*', md5($key));
    }
    // 密鑰補零至 64 字節
    $key = str_pad($key, $b, chr(0x00));

    // 内部/外部填充常量
    $ipad = str_pad('', $b, chr(0x36)); // 0x36 = 54
    $opad = str_pad('', $b, chr(0x5c)); // 0x5c = 92

    // XOR 運算生成內/外部密鑰
    $k_ipad = $key ^ $ipad;
    $k_opad = $key ^ $opad;

    // HMAC 核心:H(K ⊕ opad || H(K ⊕ ipad || data))
    return md5($k_opad . pack('H*', md5($k_ipad . $data)));
}

調用對應關係

// 原 mhash 調用
mhash(MHASH_MD5, $data, $key); // 參數順序:算法、數據、密鑰

// 兼容調用
hmac_md5($key, $data); // 參數順序:密鑰、數據(注意順序相反)

驗證測試

$key  = 'secret_key';
$data = 'message to sign';

echo 'Native mhash: ' . (extension_loaded('mhash') ? bin2hex(mhash(MHASH_MD5, $data, $key)) : 'N/A') . "\n";
echo 'Pure PHP:     ' . hmac_md5($key, $data) . "\n";
// 兩者輸出應完全一致

安全建議

  • 遷移至 hash_hmac():PHP 5.1.2+ 內置 hash_hmac('md5', $data, $key),性能更優、API 標準、支持 SHA256/SHA512 等更強算法。
  • 棄用 MD5:新系統簽名、Token、完整性校驗請使用 hash_hmac('sha256', ...) 或 hash_hmac('sha512', ...)。
  • 密鑰管理:密鑰需足夠長度(≥32 字節)、安全存儲(環境變量/密鑰管理系統)、定期輪換。

純 PHP 兼容層能快速解決遷移期擴展缺失問題,長期建議統一遷移至 hash_hmac() + SHA2 系列算法,徹底擺脫舊擴展依賴。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved