PHP 配置文件敏感信息加密保护

```html PHP 配置文件敏感信息加密保护实践

PHP 配置文件敏感信息加密保护实践

在 PHP 应用开发中,数据库密码、API 密钥、JWT 秘钥等敏感信息常存于 .envconfig.php 文件中。若配置文件意外泄露(如 Git 提交、Web 目录误暴露),将导致严重安全风险。本文介绍一种轻量、可靠且符合 PSR 标准的加密保护方案。

核心思路:运行时解密,源码零明文

不将明文密钥写入版本库,而是使用对称加密(AES-256-CBC)加密敏感字段,并将密文与加密密钥(ENCRYPTION_KEY)分离存储——密钥仅存在于服务器环境变量或安全密钥管理服务中。

示例:加密配置与解密加载

步骤 1:生成安全密钥(一次执行)

// generate-key.php
$key = random_bytes(32); // 256-bit key
echo "ENCRYPTION_KEY=" . bin2hex($key) . "\n";

步骤 2:加密敏感值(本地执行)

// encrypt-value.php
$encryptionKey = hex2bin('your_32_byte_hex_key_here'); // 来自 ENCRYPTION_KEY
$value = 'my-db-password-123';
$iv = random_bytes(16);
$ciphertext = openssl_encrypt($value, 'AES-256-CBC', $encryptionKey, 0, $iv);
$encrypted = base64_encode($iv . $ciphertext);
echo "DB_PASSWORD_ENCRYPTED={$encrypted}\n"; // 存入 .env

步骤 3:运行时安全解密(推荐封装为 ConfigLoader 类)

<?php
// src/ConfigLoader.php
class ConfigLoader
{
    private static ?array $cache = null;

    public static function get(string $key, ?string $default = null): ?string
    {
        if (self::$cache === null) {
            self::$cache = self::loadAndDecrypt();
        }
        return self::$cache[$key] ?? $default;
    }

    private static function loadAndDecrypt(): array
    {
        $env = parse_ini_file(__DIR__ . '/../.env', true) ?: [];
        $key = hex2bin($_SERVER['ENCRYPTION_KEY'] ?? '');
        if (!$key || strlen($key) !== 32) {
            throw new RuntimeException('Invalid or missing ENCRYPTION_KEY');
        }

        $decrypted = [];
        foreach ($env as $k => $v) {
            if (str_ends_with($k, '_ENCRYPTED') && is_string($v)) {
                $raw = base64_decode($v);
                $iv = substr($raw, 0, 16);
                $ciphertext = substr($raw, 16);
                $plaintext = openssl_decrypt($ciphertext, 'AES-256-CBC', $key, 0, $iv);
                $decrypted[str_replace('_ENCRYPTED', '', $k)] = $plaintext ?: null;
            } else {
                $decrypted[$k] = $v;
            }
        }
        return $decrypted;
    }
}

// 使用示例:
// $dbPassword = ConfigLoader::get('DB_PASSWORD');
⚠️ 安全提示:务必通过 php.ini 禁用 display_errors;将 .env 加入 .gitignore;生产环境通过 export ENCRYPTION_KEY=... 设置环境变量,切勿硬编码。

该方案兼顾安全性与可维护性:密钥与密文物理隔离,解密逻辑集中可控,且无需引入外部依赖。配合 Composer 自动加载与 PSR-4 规范,可无缝集成至 Laravel、Symfony 或原生项目中。

记住:加密不是万能盾牌,但它是纵深防御中不可或缺的一环——让攻击者即使拿到配置文件,也仍需突破密钥这道最后关卡。

```