PHP 数据加密最佳实践

```html PHP 数据加密最佳实践

PHP 数据加密最佳实践

在 Web 应用中,安全地处理敏感数据(如密码、API 密钥、用户身份信息)至关重要。PHP 提供了现代、可靠的加密工具,但误用仍可能导致严重风险。以下是当前(PHP 7.4+ / 8.x)推荐的加密实践。

✅ 1. 密码哈希:永远使用 password_hash()

切勿手动实现 MD5、SHA1 或 `crypt()` —— 它们已过时且不安全。

// ✅ 正确:使用 Argon2id(PHP 7.3+ 推荐)或 bcrypt
$hash = password_hash('user_password', PASSWORD_ARGON2ID, [
    'memory_cost' => 65536, // 64MB
    'time_cost'   => 4,
    'threads'     => 3
]);

// 验证时只需:
if (password_verify($input, $hash)) {
    echo "登录成功";
}

✅ 2. 对称加密:使用 sodium_crypto_secretbox()

Libsodium(PHP 7.2+ 内置)是首选——它默认启用认证加密(AEAD),防止篡改。

// 生成 256 位密钥(请安全存储!)
$key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);

// 加密
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$message = "信用卡号: 4123 4567 8901 2345";
$ciphertext = sodium_crypto_secretbox($message, $nonce, $key);

// 解密
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
echo $decrypted; // 输出原文
⚠️ 重要提醒:密钥($key)绝不能硬编码或写入代码!应通过环境变量(如 $_ENV['ENCRYPTION_KEY'])或密钥管理服务(KMS)注入。

❌ 避免的反模式

  • 不要用 mcrypt_* 函数:已废弃且不安全(PHP 7.2+ 移除);
  • 不要用 openssl_encrypt() 而不验证:若未启用 AEAD 模式(如 aes-256-gcm),需手动校验 HMAC;
  • 不要重复使用 nonce:每个加密操作必须使用唯一随机 nonce。

🔐 补充建议

  • 传输层保护:所有敏感通信强制 HTTPS(TLS 1.2+);
  • 数据库字段加密:对静态敏感数据(如身份证号)加密存储,但注意索引与查询限制;
  • 定期轮换密钥:结合密钥版本标识(如在密文前缀添加 v1:),支持平滑迁移。

安全不是功能,而是持续的过程。始终依赖经过严格审计的原生函数(如 Libsodium 和 password_*()),保持 PHP 版本更新,并遵循最小权限原则——这才是真正的“最佳实践”。

```