PHP 加密安全常见漏洞与防护
在 Web 开发中,错误的加密实践比不加密更危险——它会制造虚假的安全感。PHP 开发者常因忽视密码学原理而引入严重安全风险。
❌ 常见漏洞与错误示例
1. 使用过时/弱哈希算法
危险代码:
// ❌ MD5、SHA1 已被破解,且无盐值,易受彩虹表攻击
$password_hash = md5($password); // 绝对禁止!
$password_hash = sha1($password . $salt); // 仍不安全
2. 手动实现加盐(易出错)
危险代码:
// ❌ 自定义盐值长度不足、未使用 CSPRNG
$salt = substr(md5(time()), 0, 8); // 时间可预测,盐值重复风险高
$hash = crypt($password, '$1$' . $salt . '$');
3. 错误使用 OpenSSL(ECB 模式、固定 IV)
危险代码:
// ❌ ECB 模式不隐藏数据模式;固定 IV 导致相同明文生成相同密文
$iv = str_repeat("\x00", 16); // 危险!IV 必须随机且唯一
$encrypted = openssl_encrypt($data, 'AES-128-ECB', $key, 0); // ECB 禁用!
✅ 正确防护方案
1. 密码哈希:始终使用 password_hash()
// ✅ PHP 7.2+ 推荐:自动加盐 + 自适应成本(默认 bcrypt)
$hash = password_hash($password, PASSWORD_ARGON2ID, [
'memory_cost' => 65536, // 64MB
'time_cost' => 4,
'threads' => 3
]);
// 验证时使用 password_verify() —— 自动处理盐值与算法
if (password_verify($input, $hash)) {
echo "登录成功";
}
2. 安全对称加密:AES-GCM(认证加密)
// ✅ 使用随机 IV + 认证标签,防止篡改
function safeEncrypt($plaintext, $key) {
$iv = random_bytes(12); // GCM 推荐 12 字节 IV
$ciphertext = openssl_encrypt(
$plaintext, 'AES-128-GCM', $key, OPENSSL_RAW_DATA, $iv, $tag
);
return base64_encode($iv . $tag . $ciphertext);
}
function safeDecrypt($ciphertext, $key) {
$data = base64_decode($ciphertext);
$iv = substr($data, 0, 12);
$tag = substr($data, 12, 16);
$ciphertext = substr($data, 28);
return openssl_decrypt($ciphertext, 'AES-128-GCM', $key,
OPENSSL_RAW_DATA, $iv, $tag);
}
📌 关键安全原则
- 永不自己造轮子:避免手写加密逻辑,优先使用
password_hash()、openssl_*()(经审计) - 密钥管理:密钥≠密码,应通过环境变量或密钥管理服务(如 AWS KMS)注入,切勿硬编码
- 算法淘汰意识:定期检查 PHP 文档,停用
PASSWORD_BCRYPT以外的旧算法(如CRYPT_MD5)
安全不是功能,而是贯穿生命周期的习惯。每一次 md5() 的调用,都可能是未来数据泄露的伏笔。