PHP 配置文件敏感信息加密保护实践
在 PHP 应用开发中,数据库密码、API 密钥、JWT 秘钥等敏感信息常存于 .env 或 config.php 文件中。若配置文件意外泄露(如 Git 提交、目录遍历漏洞),将导致严重安全风险。本文介绍一种轻量、可靠、符合 PSR 标准的加密保护方案。
核心思路:运行时解密,不硬编码密钥
避免将解密密钥写死在代码中,采用环境变量 + OpenSSL 加密(AES-256-CBC)组合:
- 使用
openssl_encrypt()对敏感值预加密 - 密钥通过系统环境变量
ENCRYPTION_KEY注入(如 Docker 的--env或服务器php.ini中设置) - 应用启动时动态解密,内存中仅保留明文,不落盘
示例:加密配置与加载器
1. 加密工具脚本(encrypt.php)
<?php
// encrypt.php —— 仅本地运行一次生成密文
$key = $_ENV['ENCRYPTION_KEY'] ?? 'your-32-byte-secret-key-here!';
$value = $argv[1] ?? die("Usage: php encrypt.php 'raw_value'\n");
$ivlen = openssl_cipher_iv_length($cipher = 'AES-256-CBC');
$iv = openssl_random_pseudo_bytes($ivlen);
$encrypted = openssl_encrypt($value, $cipher, $key, 0, $iv);
echo base64_encode($iv . $encrypted) . "\n";
?>
执行:ENCRYPTION_KEY="a1b2c3...32bytes..." php encrypt.php "my_db_password" → 输出 Base64 密文。
2. 安全配置加载器(ConfigLoader.php)
<?php
class ConfigLoader
{
private static $key;
public static function init(string $key): void
{
self::$key = $key;
}
public static function decrypt(string $cipherText): string
{
if (!self::$key) {
throw new RuntimeException('Encryption key not initialized');
}
$data = base64_decode($cipherText);
$ivlen = openssl_cipher_iv_length('AES-256-CBC');
$iv = substr($data, 0, $ivlen);
$ciphertext = substr($data, $ivlen);
$decrypted = openssl_decrypt($ciphertext, 'AES-256-CBC', self::$key, 0, $iv);
if ($decrypted === false) {
throw new RuntimeException('Decryption failed: ' . openssl_error_string());
}
return $decrypted;
}
}
// 初始化密钥(推荐从环境变量读取)
ConfigLoader::init($_SERVER['ENCRYPTION_KEY'] ?? getenv('ENCRYPTION_KEY') ?? '');
?>
3. 在配置中使用
<?php
// config/database.php
require_once 'ConfigLoader.php';
return [
'host' => 'localhost',
'dbname' => 'app_db',
'username' => 'root',
'password' => ConfigLoader::decrypt('BASE64_CIPHERTEXT_HERE'),
];
?>
⚠️ 重要提醒:加密密钥必须通过环境变量注入,禁止写入代码或配置文件;生产环境禁用
display_errors,防止错误信息泄露密钥路径。
该方案兼顾安全性与可维护性:密文可版本控制,密钥隔离部署,且无需第三方扩展。配合 .gitignore 排除未加密配置,即可构建纵深防御的第一道防线。