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

PHP mcrypt 扩展缺失导致 3DES 加密报错 Call to undefined function mcrypt_module_open() 解决方案

     編輯:PHP 相關知識

PHP mcrypt 扩展缺失导致 3DES 加密报错 Call to undefined function mcrypt_module_open() 解决方案

遗留代码常用mcrypt扩展实现3DES加解密,但PHP 7.2起mcrypt已废弃并从核心移除(需PECL安装)。本文针对Windows环境,详解缺失libmcrypt.dll导致的报错排查与修复全流程。

报错现象

Fatal error: Uncaught Error: Call to undefined function mcrypt_module_open() in ...

代码片段:

$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);

根因分析

  • mcrypt_module_open属于php_mcrypt.dll扩展,依赖底层libmcrypt.dll动态库。
  • Windows下PHP目录虽有php_mcrypt.dll,但缺少libmcrypt.dll或未加入系统PATH,导致扩展加载失败(phpinfo()无mcrypt项)。

Windows 修复步骤(PHP 5.6/7.0/7.1 仍含mcrypt的版本)

  1. 获取 libmcrypt.dll:
    从官方PHP发布包(php-7.1.x-Win32-VC14-x64.zip)解压获得,或下载预编译libmcrypt-2.5.8.dll重命名为libmcrypt.dll。
  2. 部署 DLL(三处均需放置):
    ① PHP安装目录(如D:\php\)
    ② PHP扩展目录(D:\php\ext\)
    ③ Apache/Nginx二进制目录(D:\Apache24\bin\)
    ④ 系统目录(C:\Windows\System32\)最关键,确保进程能加载。
  3. 启用扩展:编辑生效的 php.ini(php --ini查看Loaded Configuration File):
extension_dir = "D:/php/ext"
extension=php_mcrypt.dll
  1. 重启 Web 服务器(Apache/Nginx + PHP-FPM)。
  2. 验证:php -m | find "mcrypt" 或 phpinfo() 搜索 mcrypt。

关键坑:修改错 php.ini

Windows下PHP可能加载C:\Windows\php.ini而非安装目录下的。务必用php --ini确认Loaded Configuration File路径,编辑该文件。

PHP 7.2+ 现代替代方案

mcrypt 已从核心移除,建议迁移至OpenSSL或Sodium(PHP 7.2+内置):

<?php
// OpenSSL 实现 3DES-CBC (兼容 Java/PHP mcrypt)
function des3Encrypt($data, $key, $iv) {
    // key 必须 24 字节 (192 bit),iv 8 字节
    $cipher = "des-ede3-cbc"; // OpenSSL 算法名
    $encrypted = openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($encrypted);
}
function des3Decrypt($b64, $key, $iv) {
    $cipher = "des-ede3-cbc";
    $decrypted = openssl_decrypt(base64_decode($b64), $cipher, $key, OPENSSL_RAW_DATA, $iv);
    return $decrypted;
}

// Sodium 现代加密 (推荐新项目)
function sodiumEncrypt($data, $key) {
    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    $cipher = sodium_crypto_secretbox($data, $nonce, $key);
    return base64_encode($nonce . $cipher);
}
function sodiumDecrypt($b64, $key) {
    $raw = base64_decode($b64);
    $nonce = substr($raw, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    $cipher = substr($raw, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    return sodium_crypto_secretbox_open($cipher, $nonce, $key);
}
?>

迁移清单:

mcrypt 函数OpenSSL 替代Sodium 替代
mcrypt_module_open(MCRYPT_3DES...)openssl_encrypt($data, 'des-ede3-cbc', ...)sodium_crypto_secretbox() (XChaCha20-Poly1305)
mcrypt_generic_init()openssl_encrypt() 内部处理自动处理 nonce
mcrypt_generic()openssl_encrypt()sodium_crypto_secretbox()
mdecrypt_generic()openssl_decrypt()sodium_crypto_secretbox_open()
Key 24 字节Key 24 字节Key 32 字节 (256 bit)
IV 8 字节IV 8 字节Nonce 24 字节

总结

  1. 老项目维护期内,按上述步骤部署libmcrypt.dll修复报错。
  2. 新项目严禁使用mcrypt,直接采用openssl_encrypt或sodium_*。
  3. 密钥管理:使用random_bytes()生成,配置中心存储,定期轮换。
  4. 加密模式:避免ECB,统一CBC/GCM,IV/Nonce每次加密随机生成并随密文存储。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved