PHP 7.2+ 已移除 mcrypt,应升级至 openssl/sodium 等现代加密库;Laravel 的 APP_KEY 必须为 32 字节随机密钥,通过环境变量安全注入,不可硬编码或提交至 Git。

composer install 报错 “ext-mcrypt is missing” 怎么办
PHP 7.2+ 已彻底移除 mcrypt 扩展,任何依赖它的 Composer 包(比如老版本的 ircmaxell/password-compat 或某些 Laravel 插件)都会安装失败。这不是 Composer 的问题,是 PHP 底层不支持了。
- 别试
pecl install mcrypt—— 它在 PHP 7.2+ 上编译不过,官方已弃用 - 检查
composer.json中是否显式 require 了含mcrypt的包,尤其是"php": ">=5.6.0"这类宽松版本约束,容易拉取过时兼容包 - 运行
composer why-not ext-mcrypt(需 composer v2.2+)快速定位哪个包在拖后腿 - 真实解法:升级到使用
openssl或sodium的现代加密库,例如用defuse/php-encryption替代基于 mcrypt 的旧实现
laravel 项目里怎么安全配置 encrypter 而不硬编码 APP_KEY
Laravel 的 Encrypter 类本身不处理密钥分发,它只负责加解密;APP_KEY 是核心密钥,泄露 = 全站 session、cookie、signed URL 全部可伪造。
-
APP_KEY必须是 32 字符随机字符串(Laravel 5.4+ 要求base64编码的 32 字节),不能是短密码、日期或可预测值 - 别写死在
.env里还提交进 Git —— 加入.gitignore,部署时通过环境变量注入(如 Docker 的-e APP_KEY=...或云平台 Secret 管理) - 如果用
php artisan key:generate,确认当前环境是生产环境且未覆盖已有密钥(否则已加密的 cookie/session 全失效) - 注意:Laravel 9+ 默认使用
AES-256-CBC,但若改用AES-256-GCM(需 PHP 7.1+ 且 OpenSSL 支持 AEAD),得手动扩展Encrypter类,原生不支持
composer require sodium 失败或 extension_loaded('sodium') 返回 false
sodium 是 PHP 7.2+ 内置扩展,不需要 composer require 安装扩展本身 —— Composer 只能装 PHP 类库,不是扩展管理器。
- 运行
php -m | grep sodium确认扩展已启用;若无输出,说明 PHP 编译时没带--with-sodium,或 ini 文件里被注释了extension=sodium - 别执行
composer require paragonie/sodium_compat除非你必须支持 PHP - 真正该
composer require的是封装库,比如paragonie/halite(高层易用 API),但它底层仍依赖sodium扩展存在 - Windows 用户注意:PHP 官方 Windows 构建默认包含
sodium,但某些第三方集成包(如 XAMPP、WampServer)可能漏掉,优先换用 php.net 官方二进制
用 openssl_encrypt 加密后,node.js 或 Python 解不出来
跨语言解密失败,90% 出在参数对不上,不是算法本身有问题。OpenSSL 的 EVP 接口行为和文档写的不一致,尤其 IV 和 padding。
-
openssl_encrypt($data, 'AES-256-CBC', $key, 0, $iv)中的$key必须是原始 32 字节密钥,不是字符串;常见错误是直接传"my-secret-key"导致实际用的是 md5("my-secret-key") 前 32 字节 - IV 必须严格 16 字节(AES-CBC),且每次加密都要随机生成、和密文一起传输;Node.js 的
createDecipheriv第二个参数是 key,第三个才是 iv —— 顺序错就全乱 - PHP 默认用 PKCS#7 填充,Python 的
Crypto.Cipher.AES需手动加pad(data, 16),而pycryptodome的PKCS7模式要显式指定mode=MODE_CBC+padding='pkcs7' - 最省事的方案:改用
sodium_crypto_secretbox(),它把 nonce、认证标签、加密数据打包在一起,跨语言兼容性好得多,且自带完整性校验
加密不是“配个扩展就能用”,密钥生命周期、IV 管理、填充方式、AEAD 选择,每一步错都可能让整个链路不可用。最容易被忽略的是:生产环境从不手动生成密钥,也不用 md5() 或 sha1() 衍生密钥 —— 直接调 random_bytes(32),然后安全存起来。











