OpenSSL 扩展
PHP 的 OpenSSL 扩展提供了丰富的加密功能,包括对称加密、非对称加密、数字签名、证书管理和哈希计算。它是 PHP 安全编程的核心扩展,广泛用于 HTTPS、JWT、数据加密等场景。
对称加密
AES 加密解密
php
<?php
declare(strict_types=1);
class AesEncryptor
{
public function __construct(
private readonly string $key,
private readonly string $cipher = 'aes-256-cbc'
) {
$keyLength = strlen($this->key);
$requiredLength = $this->getKeyLength();
if ($keyLength < $requiredLength) {
throw new \InvalidArgumentException(
"密钥长度不足,{$this->cipher} 需要 {$requiredLength} 字节"
);
}
}
private function getKeyLength(): int
{
return match ($this->cipher) {
'aes-128-cbc', 'aes-128-cfb' => 16,
'aes-192-cbc', 'aes-192-cfb' => 24,
'aes-256-cbc', 'aes-256-cfb' => 32,
default => 32,
};
}
public function encrypt(string $data): string
{
$ivLength = openssl_cipher_iv_length($this->cipher);
$iv = random_bytes($ivLength);
$encrypted = openssl_encrypt(
$data,
$this->cipher,
$this->key,
OPENSSL_RAW_DATA,
$iv
);
if ($encrypted === false) {
throw new \RuntimeException("加密失败: " . openssl_error_string());
}
// 将 IV 附加到密文前面
return base64_encode($iv . $encrypted);
}
public function decrypt(string $data): string
{
$data = base64_decode($data);
$ivLength = openssl_cipher_iv_length($this->cipher);
$iv = substr($data, 0, $ivLength);
$encrypted = substr($data, $ivLength);
$decrypted = openssl_decrypt(
$encrypted,
$this->cipher,
$this->key,
OPENSSL_RAW_DATA,
$iv
);
if ($decrypted === false) {
throw new \RuntimeException("解密失败: " . openssl_error_string());
}
return $decrypted;
}
}
$enc = new AesEncryptor('0123456789abcdef0123456789abcdef', 'aes-256-cbc');
$encrypted = $enc->encrypt('Hello World, 你好世界!');
$decrypted = $enc->decrypt($encrypted);
echo "解密结果: {$decrypted}" . PHP_EOL;非对称加密
RSA 加密解密
php
<?php
declare(strict_types=1);
// 生成 RSA 密钥对
$config = [
"digest_alg" => "sha256",
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
];
$keyPair = openssl_pkey_new($config);
// 导出私钥
openssl_pkey_export($keyPair, $privateKey);
// 导出公钥
$publicKey = openssl_pkey_get_details($keyPair)['key'];
// 公钥加密
openssl_public_encrypt('Hello World', $encrypted, $publicKey);
// 私钥解密
openssl_private_decrypt($encrypted, $decrypted, $privateKey);
echo "RSA 解密: {$decrypted}" . PHP_EOL;数字签名
php
<?php
declare(strict_types=1);
$data = '重要数据内容';
// 私钥签名
openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
// 公钥验证
$valid = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256);
echo "签名验证: " . ($valid === 1 ? '有效' : '无效') . PHP_EOL;哈希计算
php
<?php
declare(strict_types=1);
// 常用哈希
echo "MD5: " . md5('hello') . PHP_EOL;
echo "SHA1: " . sha1('hello') . PHP_EOL;
// OpenSSL hash
echo "SHA256: " . hash('sha256', 'hello') . PHP_EOL;
echo "SHA512: " . hash('sha512', 'hello') . PHP_EOL;
// HMAC
echo "HMAC-SHA256: " . hash_hmac('sha256', 'hello', 'secret_key') . PHP_EOL;
// 使用 openssl_digest
$hash = openssl_digest('hello', 'sha256');
echo "openssl SHA256: {$hash}" . PHP_EOL;证书操作
php
<?php
declare(strict_types=1);
// 读取证书
$cert = file_get_contents('/path/to/cert.pem');
$parsed = openssl_x509_parse($cert);
echo "颁发者: {$parsed['issuer']['CN']}" . PHP_EOL;
echo "有效期: {$parsed['validFrom']} - {$parsed['validTo']}" . PHP_EOL;注意事项
- 使用 AES-256-GCM 替代 CBC(PHP 7.1+)获得更好的安全性
- RSA 密钥至少使用 2048 位,推荐 4096 位
- 不要使用 md5/sha1 进行密码存储(使用 password_hash)
- 使用 OPENSSL_RAW_DATA 选项避免 Base64 自动编码
下一节
继续学习:Hash 扩展