PHP 数据加密最佳实践

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

PHP 数据加密最佳实践

在 Web 应用中,安全地处理敏感数据(如用户密码、API 密钥、个人身份信息)是开发者的首要责任。PHP 提供了成熟、安全的加密工具,但错误使用仍可能导致严重漏洞。

✅ 优先使用 password_hash()password_verify()

对密码进行哈希时,永远不要使用 md5()、sha1() 或 crypt()(无盐)。应使用 PHP 内置的现代密码哈希函数:

// ✅ 正确:使用 bcrypt(默认算法),自动加盐、自适应成本
$hash = password_hash('user_password_123', PASSWORD_DEFAULT);
// 输出类似:$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi

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

PASSWORD_DEFAULT 会随 PHP 升级自动采用更强算法(如将来支持 Argon2),确保长期安全性。

✅ 敏感数据加密:使用 sodium_crypto_secretbox()

对于需可逆加密的场景(如加密数据库中的邮箱、手机号),推荐 PHP 7.2+ 内置的 libsodium —— 经过严格审计、抗侧信道攻击的现代加密库:

// 生成并安全存储密钥(例如:base64_encode(random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES)))
$key = sodium_hex2bin('...your-32-byte-key-here...');

// 加密(自动包含 nonce)
$message = 'user@example.com';
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($message, $nonce, $key);

// 存储:base64_encode($nonce . $ciphertext)
$stored = base64_encode($nonce . $ciphertext);

// 解密
$decoded = base64_decode($stored);
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key); // 失败返回 false
⚠️ 重要提醒:密钥必须保密且唯一;绝不可硬编码在代码中,应通过环境变量或密钥管理服务(如 AWS KMS)注入。

❌ 避免已弃用/不安全方式

  • mcrypt_* 函数(PHP 7.2+ 已移除)
  • ❌ 自实现加密逻辑(如手动拼接 IV + AES)
  • ❌ 使用 ECB 模式(无扩散,明文结构暴露)
  • ❌ 将加密密钥与密文一同存储(丧失机密性)

总结:安全不是功能,而是贯穿设计、实现与运维的持续实践。始终依赖经过验证的原生函数,定期更新 PHP 版本,并结合 HTTPS、最小权限原则等纵深防御策略。

—— 坚持「少造轮子,多信标准」,是 PHP 加密最坚实的第一道防线。

```