本文目录导读:

在PHP项目中实现用户自定义加密功能,需要根据不同的需求场景选择合适的方案,以下是几种常见的实现方式,从简单到复杂:
基础用户自定义加密(对称加密)
<?php
class UserEncryption {
private string $method;
private string $key;
private string $iv;
public function __construct(string $method = 'aes-256-cbc') {
$this->method = $method;
// 从配置或数据库获取用户的自定义密钥
}
// 用户自定义加密密钥
public function setUserKey(string $userKey): void {
// 使用用户密码派生密钥
$this->key = hash('sha256', $userKey, true);
}
// 加密数据
public function encrypt(string $data): string {
$ivLength = openssl_cipher_iv_length($this->method);
$iv = openssl_random_pseudo_bytes($ivLength);
$encrypted = openssl_encrypt(
$data,
$this->method,
$this->key,
OPENSSL_RAW_DATA,
$iv
);
// 将IV和加密数据组合
return base64_encode($iv . $encrypted);
}
// 解密数据
public function decrypt(string $encryptedData): string|false {
$data = base64_decode($encryptedData);
$ivLength = openssl_cipher_iv_length($this->method);
$iv = substr($data, 0, $ivLength);
$encrypted = substr($data, $ivLength);
return openssl_decrypt(
$encrypted,
$this->method,
$this->key,
OPENSSL_RAW_DATA,
$iv
);
}
}
// 使用示例
$userEnc = new UserEncryption();
$userEnc->setUserKey('user_specific_password_123');
$encrypted = $userEnc->encrypt('敏感数据内容');
echo "加密后: " . $encrypted . PHP_EOL;
echo "解密后: " . $userEnc->decrypt($encrypted);
?>
多用户加密管理系统
<?php
class MultiUserEncryption {
private PDO $db;
public function __construct(PDO $db) {
$this->db = $db;
}
// 创建用户加密密钥
public function createUserKey(int $userId, string $userPassword): bool {
// 生成32字节随机密钥
$encryptionKey = random_bytes(32);
// 使用用户密码加密存储密钥
$protectedKey = $this->protectKeyWithPassword($encryptionKey, $userPassword);
// 存储到数据库
$stmt = $this->db->prepare(
"INSERT INTO user_encryption_keys (user_id, protected_key, created_at)
VALUES (?, ?, NOW())"
);
return $stmt->execute([$userId, base64_encode($protectedKey)]);
}
// 使用密码保护密钥
private function protectKeyWithPassword(string $key, string $password): string {
$salt = random_bytes(16);
$passwordKey = hash_pbkdf2('sha256', $password, $salt, 10000, 32, true);
$iv = random_bytes(16);
$encrypted = openssl_encrypt(
$key,
'aes-256-cbc',
$passwordKey,
OPENSSL_RAW_DATA,
$iv
);
return $salt . $iv . $encrypted;
}
// 提取用户密钥
private function extractUserKey(int $userId, string $password): ?string {
$stmt = $this->db->prepare(
"SELECT protected_key FROM user_encryption_keys WHERE user_id = ?"
);
$stmt->execute([$userId]);
$row = $stmt->fetch();
if (!$row) return null;
$data = base64_decode($row['protected_key']);
$salt = substr($data, 0, 16);
$iv = substr($data, 16, 16);
$encrypted = substr($data, 32);
$passwordKey = hash_pbkdf2('sha256', $password, $salt, 10000, 32, true);
return openssl_decrypt($encrypted, 'aes-256-cbc', $passwordKey, OPENSSL_RAW_DATA, $iv);
}
// 加密用户数据
public function encryptUserData(int $userId, string $password, string $data): string {
$key = $this->extractUserKey($userId, $password);
if (!$key) throw new Exception("无法获取用户密钥");
$iv = random_bytes(16);
$encrypted = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($iv . $encrypted);
}
// 解密用户数据
public function decryptUserData(int $userId, string $password, string $encryptedData): string {
$key = $this->extractUserKey($userId, $password);
if (!$key) throw new Exception("无法获取用户密钥");
$data = base64_decode($encryptedData);
$iv = substr($data, 0, 16);
$encrypted = substr($data, 16);
$decrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
if ($decrypted === false) throw new Exception("解密失败");
return $decrypted;
}
}
// 数据库表结构
/*
CREATE TABLE user_encryption_keys (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT UNIQUE NOT NULL,
protected_key TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
*/
?>
用户自定义加密算法选择器
<?php
class CustomEncryptionSelector {
private array $availableMethods = [
'aes-256-cbc' => 'AES-256-CBC (推荐)',
'aes-128-cbc' => 'AES-128-CBC',
'des-ede3-cbc' => '3DES',
'chacha20' => 'ChaCha20',
];
private array $userPreferences;
public function __construct(array $userPreferences = []) {
$this->userPreferences = $userPreferences;
}
// 获取可用加密方法
public function getAvailableMethods(): array {
return $this->availableMethods;
}
// 用户选择加密方法
public function setUserMethod(string $method): bool {
if (!isset($this->availableMethods[$method])) {
return false;
}
$this->userPreferences['method'] = $method;
return true;
}
// 带认证的加密(GCM模式)
public function encryptWithAuth(string $data, string $userKey): string {
$method = $this->userPreferences['method'] ?? 'aes-256-gcm';
$key = hash('sha256', $userKey, true);
$ivLength = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($ivLength);
$tag = '';
$encrypted = openssl_encrypt(
$data,
$method,
$key,
OPENSSL_RAW_DATA,
$iv,
$tag,
'',
16
);
// 包含认证标签
return base64_encode($iv . $tag . $encrypted);
}
// 解密带认证的数据
public function decryptWithAuth(string $encryptedData, string $userKey): string|false {
$method = $this->userPreferences['method'] ?? 'aes-256-gcm';
$key = hash('sha256', $userKey, true);
$data = base64_decode($encryptedData);
$ivLength = openssl_cipher_iv_length($method);
$iv = substr($data, 0, $ivLength);
$tag = substr($data, $ivLength, 16);
$encrypted = substr($data, $ivLength + 16);
return openssl_decrypt(
$encrypted,
$method,
$key,
OPENSSL_RAW_DATA,
$iv,
$tag
);
}
}
// 使用示例
$selector = new CustomEncryptionSelector();
$selector->setUserMethod('aes-256-gcm'); // 用户选择的加密方法
$userKey = 'user_specific_encryption_password';
$encrypted = $selector->encryptWithAuth('需要加密的敏感数据', $userKey);
echo "加密结果: " . $encrypted . PHP_EOL;
echo "解密结果: " . $selector->decryptWithAuth($encrypted, $userKey);
?>
数据库配置存储方案
<?php
// 数据库配置表结构
/*
CREATE TABLE user_encryption_config (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL UNIQUE,
encryption_method VARCHAR(50) DEFAULT 'aes-256-cbc',
key_derivation_iterations INT DEFAULT 100000,
salt VARCHAR(64) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
*/
class EncryptionConfigManager {
private PDO $db;
public function __construct(PDO $db) {
$this->db = $db;
}
// 保存用户加密配置
public function saveEncryptionConfig(int $userId, array $config): bool {
$stmt = $this->db->prepare(
"INSERT INTO user_encryption_config
(user_id, encryption_method, key_derivation_iterations, salt)
VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
encryption_method = VALUES(encryption_method),
key_derivation_iterations = VALUES(key_derivation_iterations),
salt = VALUES(salt)"
);
return $stmt->execute([
$userId,
$config['method'] ?? 'aes-256-cbc',
$config['iterations'] ?? 100000,
$config['salt'] ?? bin2hex(random_bytes(32))
]);
}
// 获取用户加密配置
public function getEncryptionConfig(int $userId): ?array {
$stmt = $this->db->prepare(
"SELECT * FROM user_encryption_config WHERE user_id = ?"
);
$stmt->execute([$userId]);
return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
}
}
?>
完整示例:完整的用户加密系统
<?php
// index.php - 使用示例
require_once 'user_encryption.php';
require_once 'encryption_config.php';
// 初始化数据库连接
$db = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');
$userEnc = new MultiUserEncryption($db);
$configManager = new EncryptionConfigManager($db);
// 用户注册时创建加密配置
$userId = 123;
$userPassword = 'user_secure_password_2024';
try {
// 创建用户加密密钥
$userEnc->createUserKey($userId, $userPassword);
// 保存用户加密偏好
$configManager->saveEncryptionConfig($userId, [
'method' => 'aes-256-gcm',
'iterations' => 120000,
'salt' => bin2hex(random_bytes(32))
]);
// 加密用户数据
$sensitiveData = "用户信用卡号: 4111-1111-1111-1111";
$encrypted = $userEnc->encryptUserData(
$userId,
$userPassword,
$sensitiveData
);
echo "加密成功!" . PHP_EOL;
echo "加密数据: " . $encrypted . PHP_EOL;
// 解密数据
$decrypted = $userEnc->decryptUserData(
$userId,
$userPassword,
$encrypted
);
echo "解密数据: " . $decrypted . PHP_EOL;
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
?>
安全建议
-
密钥管理
- 使用PBKDF2或bcrypt进行密钥派生
- 不要在代码中硬编码密钥
- 定期轮换加密密钥
-
加密算法选择
- 推荐使用AES-256-GCM(带认证)
- 避免使用DES或RC4等弱算法
- 使用经过验证的加密库
-
数据完整性
- 使用HMAC或GCM模式进行认证
- 验证解密后的数据完整性
- 防止篡改攻击
-
性能优化
- 缓存常用加密密钥
- 使用适当的迭代次数(100000-200000)
- 考虑使用硬件加速(如AES-NI)
-
错误处理
- 不要泄露详细的错误信息
- 实现优雅的降级策略
- 记录安全相关事件
这个实现提供了灵活的用户自定义加密功能,可以根据具体需求进行扩展和优化。