PHP加密工具功能对比:从mcrypt到sodium
PHP 提供了多套加密扩展,但各版本间差异显著。本文对比三大主流方案:mcrypt(已废弃)、openssl(广泛兼容)和 sodium(现代首选),助你选择安全可靠的加密方案。
1. mcrypt — 已淘汰的旧方案
mcrypt 在 PHP 7.1 中被弃用,7.2+ 彻底移除。其 API 设计不安全(如默认使用 ECB 模式、无认证机制),切勿在新项目中使用:
// ❌ 已废弃!PHP 7.2+ 不可用
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
mcrypt_generic_init($td, $key, '');
$ciphertext = mcrypt_generic($td, $plaintext);
2. OpenSSL — 兼容性强,需谨慎配置
openssl_encrypt() 是目前最通用的方案,支持 AES-GCM(带认证加密),但易误用(如忽略 IV 管理或未验证标签):
// ✅ 推荐:AES-128-GCM(认证加密)
$key = random_bytes(16);
$iv = random_bytes(12); // GCM 建议 12 字节 IV
$tag = '';
$ciphertext = openssl_encrypt(
$plaintext, 'aes-128-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag, '', 16
);
// 解密时必须传入 $tag 验证完整性
$decrypted = openssl_decrypt($ciphertext, 'aes-128-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
3. Sodium — 现代、安全、开箱即用
PHP 7.2+ 内置 ext/sodium,基于 libsodium,API 简洁且默认安全(自动处理 nonce、认证标签):
// ✅ 最佳实践:加密与解密一行搞定
$key = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
// 若需密钥派生(如密码加密):
$passphrase = 'my-secret-pass';
$salt = random_bytes(16);
$key = sodium_crypto_pwhash(
SODIUM_CRYPTO_SECRETBOX_KEYBYTES,
$passphrase,
$salt,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
功能对比表
| 特性 | mcrypt | OpenSSL | Sodium |
|---|---|---|---|
| PHP 版本支持 | ≤7.1 | ≥5.3(推荐 ≥7.1) | ≥7.2(内置) |
| 默认提供认证加密 | 否 | 否(需手动选 GCM/CCM) | ✅ 是(secretbox, box) |
| 密钥派生(PBKDF2/scrypt) | 否 | 需结合 hash_pbkdf2 |
✅ 内置 sodium_crypto_pwhash |
| API 复杂度 | 高(易出错) | 中(需理解 IV/tag/模式) | ✅ 低(函数式,防误用) |
结论:新项目请优先选用 sodium;遗留系统升级时,用 openssl_encrypt('aes-128-gcm') 替代 mcrypt;永远避免 ECB、CBC 无认证模式。安全不是附加功能——它是加密 API 的起点。