PHP 数据库敏感数据加密存储方案

```html PHP 数据库敏感数据加密存储方案

PHP 数据库敏感数据加密存储方案

在用户注册、支付、身份认证等场景中,密码、身份证号、手机号、银行卡号等属于敏感数据,绝不可明文存储于数据库。本文介绍一种基于 PHP 的安全、可落地的加密存储实践方案。

✅ 核心原则

  • 不自行实现加密算法 —— 使用 PHP 原生 openssl_encrypt() / openssl_decrypt()
  • 密钥严格管理 —— 密钥不硬编码,推荐使用环境变量或密钥管理服务(如 Vault)
  • 加盐+随机 IV —— 每次加密使用唯一初始化向量(IV),防止相同明文生成相同密文
  • 避免对称加密用于密码 —— 密码应使用 password_hash() 单向哈希(本文聚焦「可逆加密」场景,如身份证号)

🔐 安全加密类示例

<?php
class SecureDataCryptor
{
    private string $cipher = 'AES-256-CBC';
    private string $key;

    public function __construct(string $key)
    {
        // 使用 SHA-256 确保密钥长度合规(32字节)
        $this->key = hash('sha256', $key, true);
    }

    public function encrypt(string $plaintext): string
    {
        $ivlen = openssl_cipher_iv_length($this->cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $encrypted = openssl_encrypt(
            $plaintext,
            $this->cipher,
            $this->key,
            OPENSSL_RAW_DATA,
            $iv
        );

        // 将 IV 和密文 Base64 合并存储(IV 可公开,但必须唯一)
        return base64_encode($iv . $encrypted);
    }

    public function decrypt(string $ciphertext): ?string
    {
        $data = base64_decode($ciphertext);
        $ivlen = openssl_cipher_iv_length($this->cipher);
        $iv = substr($data, 0, $ivlen);
        $encrypted = substr($data, $ivlen);

        return openssl_decrypt(
            $encrypted,
            $this->cipher,
            $this->key,
            OPENSSL_RAW_DATA,
            $iv
        );
    }
}

// 使用示例(生产环境请从 $_ENV 或配置中心读取密钥)
$cryptor = new SecureDataCryptor($_ENV['APP_ENCRYPTION_KEY'] ?? 'your-32-byte-secret-key-here');

$idCard = '11010119900307271X';
$encrypted = $cryptor->encrypt($idCard);
echo "加密后: {$encrypted}\n"; // 存入数据库

$decrypted = $cryptor->decrypt($encrypted);
echo "解密后: {$decrypted}"; // 输出原始身份证号
?>

⚠️ 重要提醒

不要加密主键或索引字段:加密后数据不可检索、无法建立高效索引。如需模糊查询(如手机号前缀),可考虑「确定性加密」或「HMAC 摘要索引」,但需权衡安全性与功能。

最后,务必配合 最小权限数据库账户HTTPS 强制传输定期密钥轮换审计日志记录,构建纵深防御体系。

安全无小事 —— 加密是手段,而非终点。持续关注 PHP OpenSSL 文档 与 OWASP 加密最佳实践,方能守护用户信任。

```