PHP 数据脱敏与加密的区别与实践

```html PHP 数据脱敏与加密的区别与实践

PHP 数据脱敏与加密的区别与实践

在 Web 开发中,保护用户隐私是开发者的基本责任。PHP 中常涉及两类敏感数据处理技术:**数据脱敏(Masking)** 和 **数据加密(Encryption)**。二者目标相似,但原理、场景和实现方式截然不同。

核心区别

  • 脱敏:不可逆的“遮盖”操作,用于展示或日志等非业务场景,如将 13812345678 显示为 138****5678
  • 加密:可逆的数学变换,需密钥解密,用于安全存储(如密码哈希)或传输(如 AES 加密),保障机密性与完整性。

实践示例

1. 简单脱敏函数(适用于手机号、身份证号)

<?php
function maskPhone(string $phone): string
{
    if (strlen($phone) !== 11 || !preg_match('/^1[3-9]\d{9}$/', $phone)) {
        return '***';
    }
    return substr($phone, 0, 3) . '****' . substr($phone, 7);
}

echo maskPhone('13812345678'); // 输出:138****5678
?>

2. 安全加密:使用 Sodium 扩展(PHP 7.2+ 内置)

推荐替代过时的 mcrypt,Sodium 提供现代、易用的加密 API:

<?php
// 生成密钥(生产环境请安全存储)
$key = sodium_crypto_secretbox_keygen();

// 加密
$message = '用户银行卡号:6228 4800 0000 0000 000';
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($message, $nonce, $key);

// 解密(需相同 key + nonce)
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
if ($decrypted === false) {
    throw new Exception('解密失败');
}
echo $decrypted; // 恢复原文
?>

3. 密码哈希(特殊加密场景)

密码永远不应“可逆”,应使用加盐哈希:

<?php
$password = 'user@123';
$hash = password_hash($password, PASSWORD_ARGON2ID); // 推荐 Argon2
var_dump(password_verify('user@123', $hash)); // true

// 验证时无需解密,仅比对哈希值
?>
⚠️ 注意:脱敏不等于安全!脱敏后数据仍可能被推理还原(如结合其他字段)。真实敏感字段(如密码、银行卡号)必须加密存储,并遵循《个人信息保护法》及 GDPR 原则——最小必要、目的限定、明确授权。

总结:脱敏是“看得见但看不懂”的呈现策略;加密是“看不见且拿不走”的保护机制。合理组合二者——前端展示用脱敏,后端存储用加密——方为 PHP 数据安全的最佳实践。

```