本文目录导读:

在PHP项目中使用libsodium进行加密操作,主要步骤如下:
检查libsodium扩展
# 检查是否已安装 php -m | grep sodium # 如果未安装,安装方法: # Ubuntu/Debian sudo apt-get install php-sodium # CentOS/RHEL sudo yum install php-sodium # 或通过pecl安装 pecl install libsodium
验证扩展可用
<?php
// 检查扩展是否加载
if (!extension_loaded('sodium')) {
die('libsodium扩展未加载');
}
echo "libsodium已就绪\n";
// 显示版本信息
echo SODIUM_LIBRARY_VERSION;
?>
常见加密操作示例
1 对称加密(使用密钥加密解密)
<?php
// 对称加密 - 使用XChaCha20-Poly1305算法
// 生成密钥
$key = sodium_crypto_aead_xchacha20poly1305_ietf_keygen();
// 生成随机nonce
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);
// 要加密的数据
$message = "这是敏感数据";
// 关联数据(可选)
$ad = "附加认证数据";
// 加密
$ciphertext = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
$message,
$ad,
$nonce,
$key
);
// 解密
$decrypted = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
$ciphertext,
$ad,
$nonce,
$key
);
echo "解密结果:" . $decrypted . "\n";
// 清理敏感数据
sodium_memzero($key);
?>
2 非对称加密(公钥/私钥对)
<?php // 密钥对生成 $keypair = sodium_crypto_box_keypair(); $public_key = sodium_crypto_box_publickey($keypair); $secret_key = sodium_crypto_box_secretkey($keypair); // 生成nonce $nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES); // 加密消息 $message = "使用公钥加密的消息"; $ciphertext = sodium_crypto_box($message, $nonce, $keypair); // 解密 $decrypted = sodium_crypto_box_open($ciphertext, $nonce, $keypair); echo "解密结果:" . $decrypted . "\n"; ?>
3 密码哈希
<?php
// 密码哈希(适合存储用户密码)
$password = "user_password_123";
// 生成哈希
$hash = sodium_crypto_pwhash_str(
$password,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
// 验证密码
if (sodium_crypto_pwhash_str_verify($hash, $password)) {
echo "密码验证成功\n";
} else {
echo "密码错误\n";
}
// 可以调整计算参数,提高安全性
$secure_hash = sodium_crypto_pwhash_str(
$password,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
);
?>
4 生成随机数
<?php // 生成安全的随机字节 $bytes = random_bytes(32); // 使用PHP内置函数 // 使用libsodium生成随机整数 $int = random_int(1, 100); // 生成十六进制随机字符串 $hex = bin2hex(random_bytes(16)); echo "随机十六进制: " . $hex . "\n"; ?>
完整项目示例
<?php
class CryptoService {
private string $key;
public function __construct(string $key = null) {
$this->key = $key ?? sodium_crypto_secretbox_keygen();
}
// 加密数据
public function encrypt(string $plaintext): array {
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $this->key);
return [
'ciphertext' => base64_encode($ciphertext),
'nonce' => base64_encode($nonce)
];
}
// 解密数据
public function decrypt(string $ciphertext, string $nonce): ?string {
$decoded_cipher = base64_decode($ciphertext);
$decoded_nonce = base64_decode($nonce);
$decrypted = sodium_crypto_secretbox_open(
$decoded_cipher,
$decoded_nonce,
$this->key
);
return $decrypted !== false ? $decrypted : null;
}
// 密码哈希
public function hashPassword(string $password): string {
return sodium_crypto_pwhash_str(
$password,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
}
// 验证密码
public function verifyPassword(string $hash, string $password): bool {
return sodium_crypto_pwhash_str_verify($hash, $password);
}
}
// 使用示例
$crypto = new CryptoService();
// 加密数据
$data = "重要机密信息";
$encrypted = $crypto->encrypt($data);
echo "加密后: " . $encrypted['ciphertext'] . "\n";
// 解密数据
$decrypted = $crypto->decrypt($encrypted['ciphertext'], $encrypted['nonce']);
echo "解密后: " . $decrypted . "\n";
// 密码哈希
$hash = $crypto->hashPassword("mypassword");
echo "密码哈希: " . $hash . "\n";
// 验证密码
$isValid = $crypto->verifyPassword($hash, "mypassword");
echo "密码验证: " . ($isValid ? "通过" : "失败") . "\n";
?>
最佳实践建议
- 密钥管理:将密钥存储在安全的位置,如环境变量或密钥管理服务
- 每次使用新nonce:同一密钥不要重复使用相同的nonce
- 清理敏感数据:使用
sodium_memzero()清除内存中的密钥 - 使用强随机:使用
random_bytes()生成nonce和密钥 - 定期更新密钥:建立密钥轮换机制
注意事项
- PHP 7.2+ 默认内置libsodium支持
- 不要使用已弃用的函数(如
sodium_crypto_secretbox()前的版本) - 始终使用最新的算法和参数
- 生产环境中考虑使用专门的密钥管理系统
这样就完成了PHP项目中使用libsodium的基本实现!