本文目录导读:

- 使用 OpenSSL 扩展(推荐用于通用加密)
- 使用 Sodium 扩展(现代安全方案,PHP 7.2+)
- 可逆哈希(不适合加密,仅用于密码存储)
- 数据库字段级加密(MySQL AES)
- 配置文件加密
- 最佳实践建议
在PHP项目中实现加密解密,有多种方法,具体选择取决于你的需求(如加密强度、性能、是否可逆等),以下是几种常见且安全的实现方式:
使用 OpenSSL 扩展(推荐用于通用加密)
对称加密(AES-256-GCM)
<?php
/**
* AES-256-GCM 加密解密示例
* 适用于:数据传输加密、敏感信息存储
* 特点:带认证标签,防篡改
*/
class AesGcmEncryption {
private string $key;
private int $tagLength = 16; // 128位认证标签
public function __construct(string $key) {
// 确保密钥长度为32字节(256位)
$this->key = hash('sha256', $key, true);
}
/**
* 加密
* @param string $plaintext 明文
* @return string Base64编码的加密字符串(包含IV和认证标签)
*/
public function encrypt(string $plaintext): string {
$iv = openssl_random_pseudo_bytes(12); // 96位IV
$tag = '';
$ciphertext = openssl_encrypt(
$plaintext,
'aes-256-gcm',
$this->key,
OPENSSL_RAW_DATA,
$iv,
$tag,
'',
$this->tagLength
);
// 组合IV + 密文 + 认证标签
$encoded = base64_encode($iv . $ciphertext . $tag);
return $encoded;
}
/**
* 解密
* @param string $ciphertext Base64编码的加密字符串
* @return string|false 解密成功返回明文,失败返回false
*/
public function decrypt(string $ciphertext): string|false {
$decoded = base64_decode($ciphertext);
// 提取IV、密文和认证标签
$iv = substr($decoded, 0, 12);
$tag = substr($decoded, -$this->tagLength);
$encryptedData = substr($decoded, 12, -$this->tagLength);
$plaintext = openssl_decrypt(
$encryptedData,
'aes-256-gcm',
$this->key,
OPENSSL_RAW_DATA,
$iv,
$tag
);
return $plaintext;
}
}
// 使用示例
$encryption = new AesGcmEncryption('my-secret-key-12345');
$encrypted = $encryption->encrypt('Hello, World!');
echo "加密后: " . $encrypted . "\n";
$decrypted = $encryption->decrypt($encrypted);
echo "解密后: " . $decrypted . "\n";
使用 Sodium 扩展(现代安全方案,PHP 7.2+)
<?php
/**
* Sodium 加密解密(现代且安全的加密库)
* 适用于:需要最高安全标准的应用
* 特点:简单易用,内置防篡改
*/
class SodiumEncryption {
/**
* 加密
* @param string $plaintext 明文
* @param string $key 密钥(必须32字节)
* @return string Base64编码的加密结果
*/
public static function encrypt(string $plaintext, string $key): string {
// 生成随机nonce
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
// 加密
$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);
// 组合nonce + 密文
return base64_encode($nonce . $ciphertext);
}
/**
* 解密
* @param string $ciphertext Base64编码的加密字符串
* @param string $key 密钥(必须32字节)
* @return string|false 解密成功返回明文,失败返回false
*/
public static function decrypt(string $ciphertext, string $key): string|false {
$decoded = base64_decode($ciphertext);
if (mb_strlen($decoded, '8bit') < SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES) {
return false;
}
$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, $key);
// 清除敏感数据
sodium_memzero($nonce);
return $plaintext;
}
/**
* 生成安全随机密钥
* @return string 32字节的密钥
*/
public static function generateKey(): string {
return random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
}
}
// 使用示例
$key = SodiumEncryption::generateKey();
echo "密钥 (Base64): " . base64_encode($key) . "\n";
$encrypted = SodiumEncryption::encrypt('Hello, World!', $key);
echo "加密后: " . $encrypted . "\n";
$decrypted = SodiumEncryption::decrypt($encrypted, $key);
echo "解密后: " . $decrypted . "\n";
可逆哈希(不适合加密,仅用于密码存储)
<?php
/**
* 密码哈希(不可逆,用于存储密码)
* 注意:这不是加密,是单向哈希
*/
class PasswordHasher {
/**
* 创建密码哈希
*/
public static function hash(string $password): string {
return password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
}
/**
* 验证密码
*/
public static function verify(string $password, string $hash): bool {
return password_verify($password, $hash);
}
}
// 使用示例
$hash = PasswordHasher::hash('my-secret-password');
echo "密码哈希: " . $hash . "\n";
$isValid = PasswordHasher::verify('my-secret-password', $hash);
echo "密码验证: " . ($isValid ? '有效' : '无效') . "\n";
数据库字段级加密(MySQL AES)
<?php
/**
* 数据库字段加密(使用MySQL内置函数)
* 适用于:需要在数据库层面进行加密的场景
*/
class DatabaseEncryption {
private PDO $pdo;
private string $encryptionKey;
public function __construct(PDO $pdo, string $key) {
$this->pdo = $pdo;
$this->encryptionKey = $key;
}
/**
* 插入加密数据
*/
public function insertEncryptedData(string $table, string $column, string $plaintext): bool {
$sql = "INSERT INTO $table ($column) VALUES (AES_ENCRYPT(:plaintext, :key))";
$stmt = $this->pdo->prepare($sql);
return $stmt->execute([
':plaintext' => $plaintext,
':key' => $this->encryptionKey
]);
}
/**
* 查询解密数据
*/
public function getDecryptedData(string $table, string $column, int $id): ?string {
$sql = "SELECT AES_DECRYPT($column, :key) FROM $table WHERE id = :id";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([
':key' => $this->encryptionKey,
':id' => $id
]);
$result = $stmt->fetchColumn();
return $result ?: null;
}
}
配置文件加密
<?php
/**
* 配置文件加密(适用于.env文件等)
* 特点:简单,适合存储API密钥等敏感配置
*/
class ConfigEncryption {
private string $key;
private string $method = 'aes-256-cbc';
public function __construct(string $key) {
$this->key = hash('sha256', $key, true);
}
/**
* 加密配置文件值
*/
public function encryptConfigValue(string $value): string {
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($this->method));
$encrypted = openssl_encrypt($value, $this->method, $this->key, 0, $iv);
return base64_encode($iv . '::' . $encrypted);
}
/**
* 解密配置文件值
*/
public function decryptConfigValue(string $encryptedValue): string|false {
$data = base64_decode($encryptedValue);
$parts = explode('::', $data, 2);
if (count($parts) !== 2) {
return false;
}
[$iv, $encrypted] = $parts;
return openssl_decrypt($encrypted, $this->method, $this->key, 0, $iv);
}
}
// 使用示例
$configEnc = new ConfigEncryption('my-config-key');
$encryptedApiKey = $configEnc->encryptConfigValue('sk-xxxxx');
echo "加密的API密钥: " . $encryptedApiKey . "\n";
$decryptedApiKey = $configEnc->decryptConfigValue($encryptedApiKey);
echo "解密的API密钥: " . $decryptedApiKey . "\n";
最佳实践建议
-
选择合适的加密方法:
- 数据加密:使用 AES-256-GCM 或 Sodium
- 密码存储:使用 password_hash()(不可逆)
- 临时令牌:使用 openssl_random_pseudo_bytes()
-
密钥管理:
- 将密钥存储在环境变量或密钥管理服务中
- 不要硬编码密钥到代码中
- 定期轮换密钥
-
安全注意事项:
- 始终使用随机IV/nonce
- 使用认证加密(如GCM模式)防止篡改
- 不要使用过时的算法(如MD5、SHA1、DES)
- 对于敏感数据,考虑在传输层使用HTTPS
-
性能考虑:
- 对称加密比非对称加密快得多
- Sodium比OpenSSL在某些操作上更快
- 对于批量加密,考虑使用流式加密
选择哪种方法取决于你的具体需求:如果需要跨平台兼容,选OpenSSL;如果追求最高安全性且PHP 7.2+,选Sodium;如果只是密码存储,用password_hash()。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播