PHP加密工具功能对比:从mcrypt到sodium
PHP 提供了多套加密扩展,但其安全性和易用性差异显著。本文横向对比 mcrypt(已废弃)、openssl 和现代推荐的 sodium 扩展,助你选择合适方案。
1. mcrypt(⚠️ 已废弃)
PHP 7.1 起被弃用,7.2+ 完全移除。存在设计缺陷(如 ECB 模式默认、无认证加密),切勿在新项目中使用。
示例仅作历史参考(无法在 PHP ≥7.2 运行):
// ❌ 不再可用(PHP 7.2+)
$key = '16-byte-secret-key';
$iv = openssl_random_pseudo_bytes(16);
$cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
2. OpenSSL 扩展(广泛兼容)
支持 AES-GCM、AES-CBC 等主流算法,需手动处理 IV、密钥派生与认证标签,易出错。
// ✅ AES-256-GCM(推荐用于兼容旧环境)
function encryptWithOpenSSL($data, $key) {
$iv = random_bytes(12); // GCM 建议 12 字节 IV
$cipher = 'aes-256-gcm';
$tag = '';
$encrypted = openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag, '', 16);
return base64_encode($iv . $tag . $encrypted);
}
function decryptWithOpenSSL($payload, $key) {
$decoded = base64_decode($payload);
$iv = substr($decoded, 0, 12);
$tag = substr($decoded, 12, 16);
$ciphertext = substr($decoded, 28);
return openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
}
3. Sodium 扩展(✅ PHP 7.2+ 内置,强烈推荐)
基于 NaCl 库,提供“加密即服务”接口:自动处理 nonce、密钥派生、AEAD 认证,防侧信道攻击,API 极简且安全。
// ✅ libsodium:一行加密,一行解密(无需手动管理 IV/nonce)
$key = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encrypted = sodium_crypto_secretbox($data, $nonce, $key);
$decrypted = sodium_crypto_secretbox_open($encrypted, $nonce, $key);
// 或使用更高级的密钥派生(PBKDF2 + secretbox)
$passphrase = 'MySecretPass123';
$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+ 弃用 | 长期支持 | 7.2+ 默认启用 |
| 认证加密(AEAD) | ❌ 不支持 | ✅(需手动传 tag) | ✅(自动集成) |
| 密钥派生(PBKDF) | ❌ | ✅(openssl_pbkdf2) | ✅(sodium_crypto_pwhash) |
| 侧信道防护 | ❌ | ⚠️ 部分函数不安全 | ✅ 全面防护 |
| API 复杂度 | 中等(易误用) | 高(IV/tag/模式需精确匹配) | 低(“傻瓜式”安全) |
结论:新项目请直接选用 sodium;维护旧系统若无法升级 PHP,至少使用 openssl_encrypt('aes-256-gcm') 并严格校验认证标签。安全不是可选项——它是加密的起点与终点。