PHP libsodium 现代加密库使用教程
自 PHP 7.2 起,libsodium 已作为核心扩展内置(无需额外安装),它封装了业界公认的加密库 NaCl,提供**安全、易用、抗侧信道攻击**的现代密码学原语。相比 OpenSSL,libsodium 更强调“默认安全”——不暴露危险选项,避免开发者误用。
✅ 基础准备
确保 PHP ≥ 7.2,并启用扩展(通常已默认启用):
// 检查是否可用
if (!extension_loaded('sodium')) {
throw new RuntimeException('libsodium 扩展未启用');
}
echo 'libsodium 版本:' . SODIUM_LIBRARY_VERSION . "\n";
🔐 场景一:对称加密(AES 替代方案)
推荐使用 sodium_crypto_secretbox() —— AEAD 加密(认证加密),自动处理 nonce 和 MAC:
$key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES); // 32 字节密钥
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); // 24 字节随机数
$message = "Hello, libsodium!";
$ciphertext = sodium_crypto_secretbox($message, $nonce, $key);
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
var_dump($decrypted === $message); // bool(true)
🔑 场景二:公钥加密(替代 RSA)
使用 sodium_crypto_box() 实现密钥交换与加密(基于 X25519 + XSalsa20-Poly1305):
// 生成密钥对(服务端)
$server_keypair = sodium_crypto_box_keypair();
$server_secret = sodium_crypto_box_secretkey($server_keypair);
$server_public = sodium_crypto_box_publickey($server_keypair);
// 客户端生成密钥对并加密消息
$client_keypair = sodium_crypto_box_keypair();
$client_public = sodium_crypto_box_publickey($client_keypair);
$nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
$message = "Secret payload";
$ciphertext = sodium_crypto_box($message, $nonce, $server_public, $client_secret);
// 服务端解密
$decrypted = sodium_crypto_box_open($ciphertext, $nonce, $server_public, $server_secret);
🛡️ 场景三:密码哈希(替代 password_hash())
虽然 password_hash() 已足够好,但 libsodium 提供更可控的 sodium_crypto_pwhash()(Argon2i/Argon2id):
$password = "user_pass_123";
$salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);
$hash = sodium_crypto_pwhash(
SODIUM_CRYPTO_PWHASH_BYTES_MIN,
$password,
$salt,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13
);
// 验证时需保存 salt 和参数(建议用 sodium_crypto_pwhash_str() 存储字符串)
$hash_str = sodium_crypto_pwhash_str($password,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE);
var_dump(sodium_crypto_pwhash_str_verify($hash_str, $password)); // true
💡 提示:始终使用
random_bytes() 生成密钥/nonce;绝不硬编码密钥;敏感数据操作后调用 sodium_memzero($var) 清理内存。
libsodium 不是“功能更多”,而是“更难用错”。掌握以上三个核心场景,你已能构建远超 MD5/SHA1/弱 AES 的安全应用。现代 PHP 开发,从拥抱 libsodium 开始。
```