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);
$maskedLocal = substr($local, 0, 2) . str_repeat('*', max(0, strlen($local) - 2));
return $maskedLocal . '@' . $domain;
}
echo maskPhone('13812345678'); // 输出:138****5678
echo maskEmail('user@example.com'); // 输出:us**@example.com
?>
✅ 安全加密(存储/传输层防护)
使用 PHP 内置 openssl_encrypt 实现 AES-256-CBC 加密(生产环境务必使用随机 IV 并安全保管密钥):
<?php
function encrypt(string $data, string $key): array
{
$ivlen = openssl_cipher_iv_length($cipher = 'AES-256-CBC');
$iv = openssl_random_pseudo_bytes($ivlen);
$encrypted = openssl_encrypt($data, $cipher, $key, 0, $iv);
return ['data' => base64_encode($encrypted), 'iv' => base64_encode($iv)];
}
function decrypt(array $payload, string $key): ?string
{
$decrypted = openssl_decrypt(
base64_decode($payload['data']),
'AES-256-CBC',
$key,
0,
base64_decode($payload['iv'])
);
return $decrypted ?: null;
}
$key = '32-byte-secret-key-for-aes256!'; // 生产中请使用 env 或密钥管理服务
$payload = encrypt('银行卡号:6228 4800 0000 0000 000', $key);
echo "密文:" . $payload['data'] . "\n";
echo "原文:" . decrypt($payload, $key); // 银行卡号:6228 4800 0000 0000 000
?>
⚠️ 重要提醒:
• 密码应使用
password_hash() + password_verify()(bcrypt),而非对称加密;
• 脱敏不能替代加密——数据库中仍需加密存储真实敏感字段;
• IV 必须随密文一同存储(如 JSON),且每次加密必须使用新 IV。
总结:脱敏是「看得见的安全」,加密是「看不见的保障」。合理组合二者(如:数据库加密存储 + 接口响应脱敏返回),才能构建纵深防御的数据安全体系。
```