PHP加密工具功能对比:从mcrypt到sodium
PHP 提供了多套加密扩展,但安全性、易用性与维护状态差异显著。本文横向对比 mcrypt(已废弃)、openssl(通用主力)与 sodium(现代推荐),助你选对工具。
1. mcrypt — 已淘汰,切勿使用
mcrypt 自 PHP 7.1 起被弃用,7.2+ 完全移除。其 API 设计陈旧,缺乏认证加密(AEAD),且存在已知漏洞。
// ❌ 错误示例(PHP < 7.1)—— 不再支持
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $key, $iv);
$ciphertext = mcrypt_generic($td, $plaintext);
// ⚠️ 无完整性校验,易受填充预言攻击
2. OpenSSL — 灵活强大,需谨慎配置
openssl_encrypt() 和 openssl_decrypt() 是当前最广泛使用的加密函数,支持 AES-GCM(带认证)等现代模式。
// ✅ 推荐:AES-256-GCM(认证加密)
$key = random_bytes(32); // 256-bit key
$iv = random_bytes(12); // GCM 建议 96-bit IV
$ciphertext = openssl_encrypt(
$plaintext,
'aes-256-gcm',
$key,
OPENSSL_RAW_DATA,
$iv,
$tag, // 输出认证标签
'',
16 // AEAD 标签长度
);
// 解密时必须验证 $tag
$decrypted = openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
3. Sodium — 现代首选,开箱安全
sodium_crypto_secretbox()(对称)和 sodium_crypto_box()(非对称)由 Libsodium 提供,PHP 7.2+ 内置。API 极简,强制认证加密,无需手动管理 IV/nonce。
// ✅ 最佳实践:Sodium secretbox(自动处理 nonce + auth tag)
$key = sodium_crypto_secretbox_keygen(); // 256-bit 密钥
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); // 24 bytes
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
if ($decrypted === false) {
throw new Exception('解密失败:密文被篡改或密钥错误');
}
功能对比表
| 特性 | mcrypt | OpenSSL | Sodium |
|---|---|---|---|
| PHP 内置状态 | 已移除 | ✅ 一直可用 | ✅ 7.2+ |
| 默认提供认证加密 | ❌ 否 | ⚠️ 仅 GCM/CCM 模式 | ✅ 是 |
| API 复杂度 | 中高(需手动管理 IV/填充) | 中(参数多,易配错) | 低(单函数+自动 nonce) |
| 侧信道防护 | ❌ 弱 | ✅ 部分函数(如 hash_equals) |
✅ 全面(恒定时间比较/运算) |
结论:新项目请优先选用 sodium;遗留系统迁移至 openssl 时务必启用 GCM/CCM 并严格校验认证标签。永远避免 mcrypt 及不带认证的 ECB/CBC 模式。