本文目录导读:

我来详细介绍 PHP Sodium 扩展(现代加密库)的使用方法。
安装与启用
安装方法
# PHP 7.2+ 默认内置,否则需安装 # Ubuntu/Debian sudo apt-get install php-sodium # CentOS/RHEL sudo yum install php-sodium # macOS (Homebrew) brew install php-sodium
检查是否启用
<?php
echo extension_loaded('sodium') ? '已启用' : '未启用';
// 或查看函数是否存在
echo function_exists('sodium_crypto_secretbox') ? '可用' : '不可用';
核心加密功能
对称加密(密钥加密)
<?php
// 加密
function encryptData(string $plaintext): array {
$key = sodium_crypto_secretbox_keygen(); // 生成密钥
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); // 随机数
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);
return [
'ciphertext' => base64_encode($nonce . $ciphertext),
'key' => base64_encode($key)
];
}
// 解密
function decryptData(string $ciphertext, string $key): string {
$key = base64_decode($key);
$decoded = base64_decode($ciphertext);
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
$cipher = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
$plaintext = sodium_crypto_secretbox_open($cipher, $nonce, $key);
if ($plaintext === false) {
throw new Exception('解密失败');
}
return $plaintext;
}
// 使用示例
$data = "敏感信息:密码123";
$encrypted = encryptData($data);
$decrypted = decryptData($encrypted['ciphertext'], $encrypted['key']);
echo "原始数据: $data\n";
echo "加密后: " . $encrypted['ciphertext'] . "\n";
echo "解密后: $decrypted\n";
非对称加密(公钥/私钥)
<?php
// 生成密钥对
function generateKeyPair(): array {
$keypair = sodium_crypto_box_keypair();
$publicKey = sodium_crypto_box_publickey($keypair);
$secretKey = sodium_crypto_box_secretkey($keypair);
return [
'keypair' => $keypair,
'public' => base64_encode($publicKey),
'secret' => base64_encode($secretKey)
];
}
// 加密(使用接收方公钥)
function encryptWithPublicKey(string $message, string $recipientPublicKey, string $senderSecretKey): string {
$recipientPublic = base64_decode($recipientPublicKey);
$senderSecret = base64_decode($senderSecretKey);
// 创建密钥对
$senderKeypair = sodium_crypto_box_keypair_from_secretkey_and_publickey(
$senderSecret,
$recipientPublic
);
$nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
$ciphertext = sodium_crypto_box($message, $nonce, $senderKeypair);
return base64_encode($nonce . $ciphertext);
}
// 解密
function decryptWithPrivateKey(string $encrypted, string $recipientSecretKey, string $senderPublicKey): string {
$decoded = base64_decode($encrypted);
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_BOX_NONCEBYTES, '8bit');
$cipher = mb_substr($decoded, SODIUM_CRYPTO_BOX_NONCEBYTES, null, '8bit');
$recipientSecret = base64_decode($recipientSecretKey);
$senderPublic = base64_decode($senderPublicKey);
$recipientKeypair = sodium_crypto_box_keypair_from_secretkey_and_publickey(
$recipientSecret,
$senderPublic
);
$plaintext = sodium_crypto_box_open($cipher, $nonce, $recipientKeypair);
if ($plaintext === false) {
throw new Exception('解密失败');
}
return $plaintext;
}
// 使用示例
$alice = generateKeyPair();
$bob = generateKeyPair();
$message = "Hello Bob, this is Alice!";
$encrypted = encryptWithPublicKey(
$message,
$bob['public'],
$alice['secret']
);
$decrypted = decryptWithPrivateKey(
$encrypted,
$bob['secret'],
$alice['public']
);
echo "原始消息: $message\n";
echo "加密后: $encrypted\n";
echo "解密后: $decrypted\n";
密码哈希
<?php
// 哈希密码
function hashPassword(string $password): string {
$hash = sodium_crypto_pwhash_str(
$password,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE, // 计算开销
SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE // 内存限制
);
return $hash;
}
// 验证密码
function verifyPassword(string $password, string $hash): bool {
return sodium_crypto_pwhash_str_verify($hash, $password);
}
// 使用示例
$password = "MySecurePassword123!";
$hash = hashPassword($password);
echo "密码哈希: $hash\n";
echo "验证结果: " . (verifyPassword("MySecurePassword123!", $hash) ? '正确' : '错误') . "\n";
echo "错误密码验证: " . (verifyPassword("wrong", $hash) ? '正确' : '错误') . "\n";
密钥交换 (X25519)
<?php
// 生成密钥对
function generateX25519KeyPair(): array {
$keypair = sodium_crypto_kx_keypair();
$publicKey = sodium_crypto_kx_publickey($keypair);
$secretKey = sodium_crypto_kx_secretkey($keypair);
return [
'keypair' => $keypair,
'public' => base64_encode($publicKey),
'secret' => base64_encode($secretKey)
];
}
// 客户端计算共享密钥
function clientSessionKeys(string $clientKeypair, string $serverPublicKey): array {
$serverPublic = base64_decode($serverPublicKey);
$keys = sodium_crypto_kx_client_session_keys($clientKeypair, $serverPublic);
return [
'rx_key' => base64_encode($keys[0]), // 接收密钥
'tx_key' => base64_encode($keys[1]) // 发送密钥
];
}
// 服务端计算共享密钥
function serverSessionKeys(string $serverKeypair, string $clientPublicKey): array {
$clientPublic = base64_decode($clientPublicKey);
$keys = sodium_crypto_kx_server_session_keys($serverKeypair, $clientPublic);
return [
'rx_key' => base64_encode($keys[0]),
'tx_key' => base64_encode($keys[1])
];
}
消息签名
<?php
// 生成签名密钥对
function generateSignKeyPair(): array {
$keypair = sodium_crypto_sign_keypair();
$publicKey = sodium_crypto_sign_publickey($keypair);
$secretKey = sodium_crypto_sign_secretkey($keypair);
return [
'keypair' => $keypair,
'public' => base64_encode($publicKey),
'secret' => base64_encode($secretKey)
];
}
// 签名消息
function signMessage(string $message, string $secretKey): string {
$secret = base64_decode($secretKey);
$signed = sodium_crypto_sign($message, $secret);
return base64_encode($signed);
}
// 验证签名
function verifySignature(string $signedMessage, string $publicKey): string|false {
$signed = base64_decode($signedMessage);
$public = base64_decode($publicKey);
$message = sodium_crypto_sign_open($signed, $public);
return $message;
}
// 使用示例
$keys = generateSignKeyPair();
$message = "重要合同内容";
$signed = signMessage($message, $keys['secret']);
$verified = verifySignature($signed, $keys['public']);
echo "签名消息: $signed\n";
echo "验证结果: " . ($verified !== false ? $verified : '签名无效') . "\n";
高级特性
常量时间比较(防时序攻击)
<?php
// 安全的比较函数
function secureCompare(string $known, string $user): bool {
return sodium_memcmp($known, $user) === 0;
}
// 使用示例
$storedHash = '已知的哈希值';
$userInput = '用户输入';
if (secureCompare($storedHash, $userInput)) {
echo "匹配成功";
} else {
echo "匹配失败";
}
生成安全随机数
<?php
// 生成安全的随机字节
function generateRandomBytes(int $length): string {
return random_bytes($length);
}
// 生成安全的十六进制字符串
function generateHexString(int $length = 32): string {
return bin2hex(random_bytes($length));
}
// 生成安全的整数
function secureRandomInt(int $min, int $max): int {
return random_int($min, $max);
}
echo "随机字节: " . base64_encode(generateRandomBytes(16)) . "\n";
echo "十六进制: " . generateHexString() . "\n";
echo "随机整数: " . secureRandomInt(1, 100) . "\n";
最佳实践
<?php
class SecureEncryption {
private string $key;
public function __construct() {
// 从安全存储加载密钥
$this->key = $this->loadKey();
}
public function encrypt(string $data): string {
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($data, $nonce, $this->key);
return base64_encode($nonce . $ciphertext);
}
public function decrypt(string $encrypted): string {
$decoded = base64_decode($encrypted);
if ($decoded === false || mb_strlen($decoded, '8bit') < SODIUM_CRYPTO_SECRETBOX_NONCEBYTES) {
throw new InvalidArgumentException('无效的加密数据');
}
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $this->key);
if ($plaintext === false) {
throw new RuntimeException('解密失败,数据可能被篡改');
}
// 安全擦除敏感数据
sodium_memzero($ciphertext);
return $plaintext;
}
private function loadKey(): string {
// 从环境变量或安全存储加载密钥
$key = getenv('ENCRYPTION_KEY');
if ($key === false || strlen(base64_decode($key)) !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
throw new RuntimeException('无效的加密密钥');
}
return base64_decode($key);
}
// 生成新密钥
public static function generateKey(): string {
return base64_encode(sodium_crypto_secretbox_keygen());
}
}
// 使用示例
try {
$crypto = new SecureEncryption();
$encrypted = $crypto->encrypt("敏感数据");
$decrypted = $crypto->decrypt($encrypted);
echo "加密: $encrypted\n";
echo "解密: $decrypted\n";
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
重要注意事项
安全警告
<?php
// ❌ 不要使用过时的加密方式
// $encrypted = mcrypt_encrypt(...); // 已废弃
// ✅ 使用 Sodium 进行加密
// $encrypted = sodium_crypto_secretbox(...);
// ❌ 不要使用 MD5 或 SHA1 哈希密码
// $hash = md5($password);
// ✅ 使用 Sodium 的密码哈希
// $hash = sodium_crypto_pwhash_str($password);
// ❌ 不要使用简单的比较
// if ($input === $hash) { }
// ✅ 使用常量时间比较
// if (sodium_memcmp($hash, $input) === 0) { }
性能优化
<?php
// 对于频繁加密操作,重用密钥
$key = sodium_crypto_secretbox_keygen();
// 批量加密
$dataArray = ['item1', 'item2', 'item3'];
$encrypted = [];
foreach ($dataArray as $item) {
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encrypted[] = base64_encode($nonce . sodium_crypto_secretbox($item, $nonce, $key));
}
// 清理敏感数据
sodium_memzero($key);
Sodium 是现代 PHP 应用中推荐使用的加密库,提供了安全、高效的加密功能,始终使用最新版本的 PHP 和 Sodium 扩展来确保最佳安全性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播