PHP 加密密钥管理与安全存储

```html PHP 加密密钥管理与安全存储

PHP 加密密钥管理与安全存储

在 PHP 应用中,正确管理加密密钥是保障数据安全的核心环节。密钥一旦泄露或硬编码,再强的加密算法也形同虚设。

❌ 常见错误实践

以下方式绝对禁止:

  • define('ENCRYPTION_KEY', 'my-secret-123!');(硬编码于代码中)
  • 将密钥写入 config.php 并提交至 Git 仓库
  • 使用弱随机源(如 rand() 或时间戳)生成密钥

✅ 推荐安全实践

1. 使用环境变量隔离密钥

通过系统环境变量加载密钥,避免代码污染:

# Linux/macOS:启动前设置
export APP_ENCRYPTION_KEY="base64:qUJv...ZmYzI="

# PHP 中读取(推荐使用 dotenv 库管理)
$key = base64_decode(getenv('APP_ENCRYPTION_KEY') ?: '');

2. 使用 OpenSSL 安全生成与存储密钥

生成符合 AES-256-GCM 要求的 32 字节密钥:

<?php
// ✅ 安全生成密钥(仅执行一次!保存后注释掉)
$rawKey = random_bytes(32);
echo "密钥(Base64 编码):" . base64_encode($rawKey) . "\n";

// ✅ 运行时加载(从环境变量/安全配置中心获取)
$key = base64_decode($_ENV['APP_ENCRYPTION_KEY'] ?? '');
if (strlen($key) !== 32) {
    throw new RuntimeException('无效的密钥长度:必须为 32 字节');
}
?>

3. 安全加密示例(AES-256-GCM)

<?php
function encrypt(string $plaintext, string $key): string
{
    $iv = random_bytes(12); // GCM 推荐 12 字节 IV
    $tag = '';
    
    $ciphertext = openssl_encrypt(
        $plaintext,
        'aes-256-gcm',
        $key,
        OPENSSL_RAW_DATA,
        $iv,
        $tag,
        '',
        16 // 认证标签长度
    );
    
    if ($ciphertext === false) {
        throw new RuntimeException('加密失败:' . openssl_error_string());
    }
    
    return base64_encode($iv . $tag . $ciphertext);
}

function decrypt(string $encrypted, string $key): string
{
    $data = base64_decode($encrypted);
    $iv = substr($data, 0, 12);
    $tag = substr($data, 12, 16);
    $ciphertext = substr($data, 28);
    
    $plaintext = openssl_decrypt(
        $ciphertext,
        'aes-256-gcm',
        $key,
        OPENSSL_RAW_DATA,
        $iv,
        $tag
    );
    
    if ($plaintext === false) {
        throw new RuntimeException('解密失败或密钥错误');
    }
    
    return $plaintext;
}
?>
⚠️ 关键提醒:密钥必须严格保密;IV 和 tag 可公开传输(但需与密文绑定);永远不要重用 IV;生产环境禁用 display_errors 防止密钥意外泄露。

终极建议:将密钥交由专业密钥管理服务(如 HashiCorp Vault、AWS KMS 或 Azure Key Vault),通过 API 动态获取,实现密钥轮换与审计追踪。安全不是功能,而是持续的过程。

```