PHP加密工具功能对比:从mcrypt到sodium
PHP 提供了多套加密扩展,但功能定位与安全性差异显著。本文对比三类主流工具:mcrypt(已废弃)、openssl(通用主力)和 sodium(现代首选)。
1. mcrypt —— 已淘汰的遗留方案
mcrypt 自 PHP 7.1 起被弃用,7.2+ 完全移除。其 API 设计陈旧、默认使用不安全的 ECB 模式,且缺乏认证加密(AEAD)支持。
⚠️ 不推荐在新项目中使用,也不应依赖任何基于 mcrypt 的旧代码库。
2. OpenSSL —— 灵活但需谨慎配置
openssl_encrypt() 和 openssl_decrypt() 支持 AES-128-GCM、AES-256-CBC 等主流算法,但易因参数误配导致安全隐患(如 IV 重用、缺少消息认证)。
// ✅ 推荐:AES-256-GCM(带认证加密)
$key = random_bytes(32); // 256-bit key
$iv = random_bytes(12); // GCM recommended IV length
$plaintext = "Hello, secure world!";
$ciphertext = openssl_encrypt($plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
$encrypted = base64_encode($iv . $tag . $ciphertext);
// 解密时需拆分 IV + tag + ciphertext
$decoded = base64_decode($encrypted);
$iv = substr($decoded, 0, 12);
$tag = substr($decoded, 12, 16);
$cipher = substr($decoded, 28);
$decrypted = openssl_decrypt($cipher, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
echo $decrypted; // Hello, secure world!
3. Sodium —— 现代、安全、开箱即用
ext-sodium(PHP 7.2+ 内置)提供经过严格审计的密码学原语,API 简洁且默认安全(如自动处理 nonce、强制 AEAD)。推荐用于绝大多数场景。
// ✅ 推荐:使用 crypto_secretbox(XSalsa20-Poly1305)
$key = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$plaintext = "Hello, sodium world!";
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);
$encrypted = base64_encode($nonce . $ciphertext);
// 解密
$decoded = base64_decode($encrypted);
$nonce = substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$cipher = substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$decrypted = sodium_crypto_secretbox_open($cipher, $nonce, $key);
if ($decrypted === false) {
throw new Exception('Decryption failed!');
}
echo $decrypted; // Hello, sodium world!
功能对比简表
| 特性 | mcrypt | OpenSSL | Sodium |
|---|---|---|---|
| PHP 内置状态 | 已移除 | ✅ 默认启用 | ✅ PHP 7.2+ |
| AEAD 支持 | ❌ | ✅(需手动指定 GCM/CCM) | ✅(secretbox, sealed_box) |
| 密钥派生 | ❌ | ✅(PKCS5_PBKDF2_HMAC) |
✅(crypto_pwhash,抗 GPU 暴力) |
| API 易用性 | ❌(易出错) | ⚠️(需理解 IV/模式/填充) | ✅(函数单一职责,少参数) |
结论:新项目请优先选用 sodium;维护旧系统若无法升级,至少确保 openssl 使用 GCM 模式并正确管理 nonce/IV。永远避免 mcrypt 及 md5()/sha1() 等非加密哈希做密码存储。