PHP加密工具功能对比:从mcrypt到sodium
PHP 提供了多套加密扩展,但其安全性、易用性与维护状态差异显著。本文聚焦三大主流方案:mcrypt(已废弃)、openssl(通用主力)与 sodium(现代首选),通过功能与代码实测对比,助你做出安全选型。
1. mcrypt —— 已淘汰的“历史遗迹”
mcrypt 自 PHP 7.1 起被标记为 deprecated,7.2+ 完全移除。它缺乏认证加密(AEAD)、密钥派生不安全,且 API 易误用:
<?php
// ❌ 危险示例(PHP < 7.1)—— 无认证、ECB模式弱
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
mcrypt_generic_init($td, $key, '');
$ciphertext = mcrypt_generic($td, $plaintext);
mcrypt_generic_deinit($td);
?>
⚠️ 提示:切勿在新项目中使用 mcrypt;升级至 PHP 7.2+ 后必须迁移。
2. OpenSSL —— 灵活但需谨慎
openssl_encrypt() 支持 AES-GCM(带认证),是当前最广泛兼容的方案:
<?php
$key = random_bytes(32); // AES-256
$iv = random_bytes(12); // GCM 推荐 12 字节 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);
?>
✅ 优势:PHP 5.3+ 内置,支持主流算法;❌ 缺陷:API 复杂,易遗漏 $tag 或 IV 重用,错误处理不直观。
3. Sodium —— 现代加密的黄金标准(PHP 7.2+)
ext-sodium(基于 libsodium)提供高安全、零配置的 AEAD 加密,是 PHP 官方推荐方案:
<?php
// ✅ 一行加密,自动处理 nonce、认证、填充
$key = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);
// ✅ 一行解密,失败直接返回 false(无需异常捕获)
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
if ($decrypted === false) {
throw new Exception('解密失败:密钥错误或数据篡改');
}
?>
✅ 优势:默认启用认证加密、抗时序攻击、简洁 API、内置密钥派生(sodium_crypto_pwhash);✅ 兼容 Libsodium 的跨语言生态。
对比总结
| 特性 | mcrypt | OpenSSL | Sodium |
|---|---|---|---|
| PHP 版本支持 | ≤ 7.1(废弃) | ≥ 5.3 | ≥ 7.2(核心扩展) |
| 默认认证加密 | ❌ 不支持 | ✅(需手动指定 GCM + tag) | ✅(secretbox 内置) |
| 密钥派生(PBKDF2/scrypt) | ❌ | ✅(openssl_pbkdf2) |
✅(sodium_crypto_pwhash,更安全) |
| 推荐指数 | ⛔ 绝对避免 | ⭐⭐⭐☆(需严谨封装) | ⭐⭐⭐⭐⭐(首选) |
结论:新项目请坚定选择 sodium;遗留系统若暂无法升级 PHP,务必使用 openssl_encrypt('aes-256-gcm') 并严格管理 IV/tag。安全不是选项,而是加密的起点。