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

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

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

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

核心区别

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

实践示例

✅ 数据脱敏(展示层防护)

适用于前端展示、日志记录、测试数据生成——不改变原始值,仅隐藏部分字符:

<?php
function maskPhone(string $phone): string {
    return preg_replace('/^(\d{3})\d{4}(\d{4})$/', '$1****$2', $phone);
}

function maskEmail(string $email): string {
    [$local, $domain] = explode('@', $email, 2);
    $maskedLocal = substr($local, 0, 1) . str_repeat('*', strlen($local) - 2) . substr($local, -1);
    return $maskedLocal . '@' . $domain;
}

echo maskPhone('13812345678'); // 输出:138****5678
echo maskEmail('user@example.com'); // 输出:u***r@example.com ?>

✅ 安全加密(存储/传输层防护)

使用 PHP 内置函数实现强加密。推荐 password_hash() 存储密码,openssl_encrypt() 加密结构化数据:

<?php
// ✅ 密码哈希(单向,防彩虹表)
$password = 'MyP@ssw0rd!';
$hash = password_hash($password, PASSWORD_ARGON2ID, ['memory_cost' => 65536, 'time_cost' => 4]);
var_dump(password_verify('MyP@ssw0rd!', $hash)); // bool(true)

// ✅ AES-256-GCM 加密(双向,需密钥管理)
$key = openssl_random_pseudo_bytes(32); // 生产环境请安全存储密钥!
$ivlen = openssl_cipher_iv_length($cipher = 'aes-256-gcm');
$iv = openssl_random_pseudo_bytes($ivlen);
$data = '订单号: ORD-2024-7890, 金额: ¥299.00';

$ciphertext = openssl_encrypt($data, $cipher, $key, $options = 0, $iv, $tag);

// 解密时需同时提供 $iv 和 $tag
$decrypted = openssl_decrypt($ciphertext, $cipher, $key, $options = 0, $iv, $tag);
echo "原文: $data\n";
echo "密文: " . base64_encode($ciphertext) . "\n";
echo "解密: $decrypted"; // 输出原文
?>
⚠️ 注意事项: • 脱敏不替代加密——脱敏后数据仍可能被推断; • 密码必须用 password_hash(),禁用 md5/sha1; • 加密密钥切勿硬编码,应使用环境变量或密钥管理服务(如 AWS KMS)。

总结:脱敏是「看得见的安全」,加密是「看不见的保险」。合理分层使用——展示用脱敏,存储/传输用加密,方能兼顾用户体验与数据合规(如 GDPR、《个人信息保护法》)。

```