PHP加密密钥严禁硬编码,必须通过环境变量或权限严格的外部配置文件(如.env)管理,使用getenv()读取,密钥长度须符合算法要求(如AES-256需32字节随机生成),并实施密钥轮换与旧数据重加密。

PHP加密密钥不能写在代码里
硬编码密钥(比如直接在 config.php 里写 $key = 'abc123...';)等于把锁芯贴在门上。Git 提交、服务器备份、日志泄露、IDE 快照都可能暴露它。一旦被读到,AES 加密、JWT 签名、数据库连接密码全等于没设防。
必须让密钥脱离源码,且不随部署包流转。可行路径只有两条:环境变量、外部配置文件(需严格权限控制),二者都得配合 Web 服务器隔离机制。
用 $_ENV 或 getenv() 读取环境变量最稳妥
PHP 7.1+ 默认启用 variables_order = "EGPCS",$_ENV 可用;但更推荐用 getenv('APP_KEY') —— 它不依赖 php.ini 配置,兼容性更强,且不会因 register_globals 类旧设置引发歧义。
- Linux/Nginx 下,在 PHP-FPM pool 配置中加:
env[APP_KEY] = "your-32-byte-random-string-here" - Docker 中用
-e APP_KEY=...或environment:段落注入 - Laravel/Lumen 项目直接在
.env里写APP_KEY=...,框架底层调用getenv()读取 - 绝对不要用
putenv()在 PHP 脚本里动态设置——它只对当前请求生效,且易被覆盖
.env 文件权限必须设为 600,且禁止 Web 直接访问
.env 是常见选择,但本质仍是「外部配置文件」,安全全靠两层防护:文件系统权限 + Web 服务器路由拦截。
立即学习“PHP免费学习笔记(深入)”;
- 部署后立刻执行:
chmod 600 .env(仅属主可读写,其他用户无权限) - Nginx 配置中加:
location ~ /\.env { deny all; },Apache 加RedirectMatch 404 \.env$ - 不要把
.env放在public/或webroot/下——哪怕加了 deny 规则,目录遍历漏洞或配置失误仍可能绕过 - CI/CD 流水线中避免 echo 密钥到日志,Git 里禁用
.env,改用模板.env.example+ 运行时注入
密钥长度和生成方式直接影响加密强度
很多开发者用 md5('password') 或短字符串当 AES 密钥,结果加密形同虚设。PHP 的 openssl_encrypt() 对密钥长度敏感,且不同算法要求不同:
- AES-256-CBC 要求密钥正好 32 字节:
random_bytes(32)生成,别用 base64_encode() 后截断 - JWT HS256 签名密钥建议 ≥32 字节,可用
bin2hex(random_bytes(32))生成可读字符串 - 别用时间戳、主机名、固定字符串拼接——熵值太低,容易被 rainbow table 破解
- 生产环境密钥绝不能复用开发密钥,每次部署应重新生成并安全分发
最常被忽略的点:密钥轮换没有配套措施。换密钥后,旧数据若未重新加密,就会解密失败——这问题在 JWT 过期逻辑、数据库字段加密场景里特别隐蔽。











