重要提示:mcrypt 擴展已於 PHP 7.1 棄用、PHP 7.2 移除(遷移至 PECL)。現代專案請改用 OpenSSL (AES-GCM、ChaCha20-Poly1305) 或 libsodium (PHP 7.2+ 內建),提供更安全、經過審計的加密原語。本文僅供維護 PHP 5.x/7.0-7.1 遺留系統參考。
mcrypt 是對 libmcrypt C 庫的 PHP 封裝,支援對稱加密演算法:
安全警告:ECB 模式不安全(相同明文產生相同密文)、DES/3DES 強度不足、Blowfish 產生弱金鑰。新系統嚴禁使用,請採用 AES-GCM (OpenSSL) 或 XChaCha20-Poly1305 (libsodium)。
mcrypt 依賴 libmcrypt 與 mhash (可選,提供雜湊介面),安裝順序不可顛倒:
# 下載
wget https://sourceforge.net/projects/mcrypt/files/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz
tar -zxvf libmcrypt-2.5.8.tar.gz
cd libmcrypt-2.5.8
# 配置:指定安裝前綴 (建議 /usr/local)
./configure --prefix=/usr/local
make
make install
# 更新動態連結器快取
ldconfig
wget https://sourceforge.net/projects/mhash/files/mhash/0.9.9.9/mhash-0.9.9.9.tar.gz
tar -zxvf mhash-0.9.9.9.tar.gz
cd mhash-0.9.9.9
./configure --prefix=/usr/local
make
make install
ldconfig
wget https://sourceforge.net/projects/mcrypt/files/MCrypt/2.6.8/mcrypt-2.6.8.tar.gz
tar -zxvf mcrypt-2.6.8.tar.gz
cd mcrypt-2.6.8
# 關鍵:指定 libmcrypt 庫路徑,否則 configure 找不到
LD_LIBRARY_PATH=/usr/local/lib ./configure --prefix=/usr/local --with-libmcrypt-prefix=/usr/local
make
make install
關鍵點:LD_LIBRARY_PATH=/usr/local/lib讓連結器在配置階段找到libmcrypt.so,否則會報libmcrypt not found錯誤。
前提:擁有與目前運行 PHP 版本完全一致的原始碼套件 (含 ext/mcrypt 目錄)。
# 1. 進入 PHP 原始碼的 mcrypt 擴展目錄
cd /path/to/php-5.6.40/ext/mcrypt
# 2. 執行 phpize (使用目標 PHP 安裝路徑下的 phpize)
/usr/local/php/bin/phpize
# 3. 配置:指定 php-config 路徑與 libmcrypt 路徑
./configure \
--with-php-config=/usr/local/php/bin/php-config \
--with-mcrypt=/usr/local
# 4. 編譯安裝
make && make install
# 5. 輸出類似:Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/
編輯 php.ini 加入:
extension=mcrypt.so
重啟 PHP-FPM/Apache:
systemctl restart php-fpm
# 或
/usr/local/apache2/bin/apachectl graceful
驗證:
php -m | grep mcrypt
php -i | grep -A 10 "mcrypt support"
需重新編譯整個 PHP:
cd /path/to/php-src
# 1. 清理舊建置 (必要)
make clean
# 2. 取得原有 configure 參數 (從 phpinfo() 或舊建置記錄)
# 範例參數:
./configure \
--prefix=/usr/local/php \
--with-apxs2=/usr/local/apache/bin/apxs \
--with-mcrypt=/usr/local \
--with-mhash=/usr/local \
--with-libxml-dir=/usr/local \
--enable-mbstring \
--enable-sockets \
...其他原有參數...
# 3. 編譯安裝
make
make install
| 錯誤 | 原因 | 解決 |
|---|---|---|
configure: error: mcrypt.h not found |
libmcrypt 開發套件未安裝或路徑錯誤 | 安裝 libmcrypt-devel (RPM) / libmcrypt-dev (DEB),或指定 --with-mcrypt=/usr/local |
ld: cannot find -lmcrypt |
連結器找不到 libmcrypt.so | 執行 ldconfig,確認 /usr/local/lib 在 /etc/ld.so.conf.d/ 中 |
PHP Warning: PHP Startup: Unable to load dynamic library 'mcrypt.so' |
模組編譯版本不匹配 (API/ABI/Thread Safety) | 確認 phpize、php-config 來自目標 PHP 安裝,重新 make clean && phpize && configure... |
Call to undefined function mcrypt_encrypt() |
擴展未載入或名稱錯誤 | 檢查 php.ini extension=mcrypt.so、重啟服務、php -m 確認 |
mcrypt_module_open() deprecated |
PHP 7.1+ 棄用警告 | 遷移至 OpenSSL/libsodium,或加入 error_reporting(E_ALL & ~E_DEPRECATED) 暫時抑制 |
<?php
// AES-256-GCM (認證加密,推薦)
$key = random_bytes(32); // 256-bit 金鑰
$nonce = random_bytes(12); // 96-bit nonce (GCM 建議 12 bytes)
$data = "機密資料";
$tag = null;
$ciphertext = openssl_encrypt($data, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $nonce, $tag);
// 儲存: $nonce . $tag . $ciphertext
$decrypted = openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $nonce, $tag);
<?php
// XChaCha20-Poly1305 (現代、快速、抗旁路攻擊)
$key = sodium_crypto_aead_xchacha20poly1305_ietf_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);
$data = "機密資料";
$ciphertext = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($data, '', $nonce, $key);
// 儲存: $nonce . $ciphertext
$decrypted = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($ciphertext, '', $nonce, $key);
mcrypt_* 函數的程式碼位置aes-256-cbc (OpenSSL) 或 aes-256-gcm (推薦)mcrypt 曾是 PHP 加密的主力,但因底層庫長期未維護、API 設計缺陷 (易誤用 ECB、靜態 IV)、缺乏認證加密模式,已被社區淘汰。維護舊系統時請嚴格遵循依賴安裝順序與 phpize 版本匹配原則;新專案務必採用 OpenSSL AES-GCM 或 Sodium XChaCha20-Poly1305,並妥善管理金鑰生命週期 (輪換、HSM/KMS 整合),構建符合現代密碼學標準的安全體系。