本文目录导读:

- 项目结构
- 数据库配置 (config/config.php)
- 数据库类 (src/Database.php)
- 加密工具类 (src/Crypto.php)
- 密钥管理器 (src/KeyManager.php)
- 审计日志类 (src/AuditLogger.php)
- 数据库schema (sql/schema.sql)
- API接口 (public/index.php)
- README文件 (README.md)
- API使用示例
- 安全注意事项
- 扩展建议
- 使用说明
我将为您实现一个基于PHP的简单密钥管理系统,包含密钥生成、存储、加密和轮换功能。
项目结构
key-management/
├── config/
│ └── config.php
├── src/
│ ├── Database.php
│ ├── Crypto.php
│ ├── KeyManager.php
│ └── AuditLogger.php
├── public/
│ └── index.php
├── sql/
│ └── schema.sql
└── README.md
数据库配置 (config/config.php)
<?php
return [
'database' => [
'host' => 'localhost',
'name' => 'key_manager',
'user' => 'root',
'pass' => '',
'charset' => 'utf8mb4'
],
'settings' => [
'key_length' => 32, // 256位密钥
'iv_length' => 16, // 128位IV
'hash_algorithm' => 'sha256',
'cipher_method' => 'AES-256-CBC',
'key_expiry_days' => 90,
'max_retry_attempts' => 3
],
'encryption' => [
'master_key_env' => 'MASTER_KEY', // 主密钥从环境变量获取
'key_prefix' => 'kms_'
]
];
数据库类 (src/Database.php)
<?php
class Database {
private static $instance = null;
private $connection;
private function __construct($config) {
try {
$dsn = "mysql:host={$config['host']};dbname={$config['name']};charset={$config['charset']}";
$this->connection = new PDO($dsn, $config['user'], $config['pass'], [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
} catch (PDOException $e) {
throw new Exception('Database connection failed: ' . $e->getMessage());
}
}
public static function getInstance() {
if (self::$instance === null) {
$config = require __DIR__ . '/../config/config.php';
self::$instance = new self($config['database']);
}
return self::$instance;
}
public function getConnection() {
return $this->connection;
}
public function execute($query, $params = []) {
$stmt = $this->connection->prepare($query);
$stmt->execute($params);
return $stmt;
}
public function fetchAll($query, $params = []) {
$stmt = $this->execute($query, $params);
return $stmt->fetchAll();
}
public function fetchOne($query, $params = []) {
$stmt = $this->execute($query, $params);
return $stmt->fetch();
}
}
加密工具类 (src/Crypto.php)
<?php
class Crypto {
private $cipher_method;
private $master_key;
private $iv_length;
public function __construct($config) {
$this->cipher_method = $config['settings']['cipher_method'];
$this->iv_length = $config['settings']['iv_length'];
// 从环境变量获取主密钥
$masterKeyEnv = getenv($config['encryption']['master_key_env']);
if (!$masterKeyEnv) {
throw new Exception('Master key not found in environment');
}
$this->master_key = hash('sha256', $masterKeyEnv, true);
}
// 加密数据
public function encrypt($data, $key) {
$iv = openssl_random_pseudo_bytes($this->iv_length);
$encrypted = openssl_encrypt(
$data,
$this->cipher_method,
$key,
OPENSSL_RAW_DATA,
$iv
);
if ($encrypted === false) {
throw new Exception('Encryption failed');
}
// 组合 IV 和加密数据
$encoded = base64_encode($iv . $encrypted);
return $encoded;
}
// 解密数据
public function decrypt($data, $key) {
$decoded = base64_decode($data);
$iv = substr($decoded, 0, $this->iv_length);
$encrypted = substr($decoded, $this->iv_length);
$decrypted = openssl_decrypt(
$encrypted,
$this->cipher_method,
$key,
OPENSSL_RAW_DATA,
$iv
);
if ($decrypted === false) {
throw new Exception('Decryption failed');
}
return $decrypted;
}
// 生成随机密钥
public function generateKey($length = 32) {
return random_bytes($length);
}
// 生成主密钥哈希
public function hashKey($key) {
return hash('sha256', $key);
}
// 为特定密钥生成唯一ID
public function generateKeyId() {
return bin2hex(random_bytes(16));
}
}
密钥管理器 (src/KeyManager.php)
<?php
require_once 'Database.php';
require_once 'Crypto.php';
class KeyManager {
private $db;
private $crypto;
private $config;
public function __construct() {
$this->config = require __DIR__ . '/../config/config.php';
$this->db = Database::getInstance();
$this->crypto = new Crypto($this->config);
}
// 生成新密钥
public function generateKey($name, $type = 'general', $expiryDays = null) {
// 生成密钥对
$key = $this->crypto->generateKey($this->config['settings']['key_length']);
$keyId = $this->crypto->generateKeyId();
// 使用主密钥派生密钥
$masterKey = $this->getMasterKey();
$encryptionKey = $this->deriveKey($keyId, $masterKey);
// 加密密钥
$encryptedKey = $this->crypto->encrypt($key, $encryptionKey);
// 计算过期时间
$expiryDays = $expiryDays ?: $this->config['settings']['key_expiry_days'];
$expiresAt = date('Y-m-d H:i:s', strtotime("+{$expiryDays} days"));
// 准备API密钥
$apiKey = $keyId . ':' . bin2hex($key);
$apiHash = $this->crypto->hashKey($apiKey);
try {
// 存储密钥元数据和加密内容
$sql = "INSERT INTO keys_registry
(key_id, name, type, encrypted_key, api_key_hash,
status, created_at, expires_at, last_used_at)
VALUES (?, ?, ?, ?, ?, 'active', NOW(), ?, NULL)";
$this->db->execute($sql, [
$keyId,
$name,
$type,
$encryptedKey,
$apiHash,
$expiresAt
]);
// 记录审计日志
$this->logAudit('key_generation', [
'key_id' => $keyId,
'name' => $name,
'type' => $type
]);
return [
'key_id' => $keyId,
'api_key' => $apiKey,
'name' => $name,
'expires_at' => $expiresAt
];
} catch (Exception $e) {
throw new Exception('Failed to generate key: ' . $e->getMessage());
}
}
// 获取密钥(通过API密钥)
public function getKey($apiKey) {
// 验证API密钥格式
if (!preg_match('/^([a-f0-9]+):([a-f0-9]+)$/', $apiKey, $matches)) {
throw new Exception('Invalid API key format');
}
$keyId = $matches[1];
$keyHash = $this->crypto->hashKey($apiKey);
// 查找密钥
$keyData = $this->db->fetchOne(
"SELECT * FROM keys_registry WHERE key_id = ? AND api_key_hash = ?",
[$keyId, $keyHash]
);
if (!$keyData) {
throw new Exception('Invalid API key');
}
// 检查密钥状态
if ($keyData['status'] !== 'active') {
throw new Exception('Key is not active');
}
// 检查是否过期
if (strtotime($keyData['expires_at']) < time()) {
$this->deactivateKey($keyId, 'expired');
throw new Exception('Key has expired');
}
// 解密密钥
$masterKey = $this->getMasterKey();
$encryptionKey = $this->deriveKey($keyId, $masterKey);
$decryptedKey = $this->crypto->decrypt($keyData['encrypted_key'], $encryptionKey);
// 更新最后使用时间
$this->db->execute(
"UPDATE keys_registry SET last_used_at = NOW(),
usage_count = usage_count + 1 WHERE key_id = ?",
[$keyId]
);
// 记录审计日志
$this->logAudit('key_access', ['key_id' => $keyId]);
return [
'key_id' => $keyId,
'name' => $keyData['name'],
'key' => bin2hex($decryptedKey),
'expires_at' => $keyData['expires_at']
];
}
// 轮换密钥
public function rotateKey($keyId) {
$keyData = $this->db->fetchOne(
"SELECT * FROM keys_registry WHERE key_id = ?",
[$keyId]
);
if (!$keyData) {
throw new Exception('Key not found');
}
// 创建新密钥
$newKey = $this->crypto->generateKey($this->config['settings']['key_length']);
$newEncryptedKey = $this->crypto->encrypt(
$newKey,
$this->deriveKey($keyId, $this->getMasterKey())
);
// 更新密钥内容
$this->db->execute(
"UPDATE keys_registry SET
encrypted_key = ?,
rotated_at = NOW(),
rotation_count = rotation_count + 1
WHERE key_id = ?",
[$newEncryptedKey, $keyId]
);
// 生成新的API密钥
$newApiKey = $keyId . ':' . bin2hex($newKey);
// 记录审计日志
$this->logAudit('key_rotation', ['key_id' => $keyId]);
return [
'key_id' => $keyId,
'api_key' => $newApiKey
];
}
// 撤销密钥
public function revokeKey($keyId, $reason = 'manual') {
$this->deactivateKey($keyId, 'revoked', $reason);
// 记录审计日志
$this->logAudit('key_revocation', [
'key_id' => $keyId,
'reason' => $reason
]);
return true;
}
// 列出所有密钥
public function listKeys($status = null) {
$query = "SELECT id, key_id, name, type, status,
created_at, expires_at, last_used_at, usage_count
FROM keys_registry";
$params = [];
if ($status) {
$query .= " WHERE status = ?";
$params[] = $status;
}
$query .= " ORDER BY created_at DESC";
return $this->db->fetchAll($query, $params);
}
// 检查密钥健康状况
public function checkHealth() {
$stats = $this->db->fetchOne(
"SELECT
COUNT(*) as total,
SUM(status = 'active') as active,
SUM(status = 'revoked') as revoked,
SUM(status = 'expired') as expired
FROM keys_registry"
);
return $stats;
}
// 派生加密密钥
private function deriveKey($keyId, $masterKey) {
return hash_hmac('sha256', $keyId, $masterKey, true);
}
// 获取主密钥
private function getMasterKey() {
$masterKeyEnv = getenv($this->config['encryption']['master_key_env']);
if (!$masterKeyEnv) {
throw new Exception('Master key not found');
}
return hash('sha256', $masterKeyEnv, true);
}
// 停用密钥
private function deactivateKey($keyId, $status, $reason = null) {
$this->db->execute(
"UPDATE keys_registry SET status = ?,
revoked_at = NOW(), revoke_reason = ? WHERE key_id = ?",
[$status, $reason, $keyId]
);
}
// 记录审计日志
private function logAudit($action, $details) {
$sql = "INSERT INTO audit_logs (action, details, ip_address, created_at)
VALUES (?, ?, ?, NOW())";
$this->db->execute($sql, [
$action,
json_encode($details),
$_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'
]);
}
}
审计日志类 (src/AuditLogger.php)
<?php
class AuditLogger {
private $db;
public function __construct() {
$this->db = Database::getInstance();
}
public function log($action, $details, $user = null) {
$sql = "INSERT INTO audit_logs (action, details, user_name, ip_address, created_at)
VALUES (?, ?, ?, ?, NOW())";
return $this->db->execute($sql, [
$action,
json_encode($details),
$user ?? $_SESSION['user'] ?? null,
$_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'
]);
}
public function getLogs($limit = 50) {
return $this->db->fetchAll(
"SELECT * FROM audit_logs ORDER BY created_at DESC LIMIT ?",
[$limit]
);
}
}
数据库schema (sql/schema.sql)
-- 创建数据库
CREATE DATABASE IF NOT EXISTS key_manager;
USE key_manager;
-- 密钥表
CREATE TABLE IF NOT EXISTS keys_registry (
id INT AUTO_INCREMENT PRIMARY KEY,
key_id VARCHAR(32) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
type VARCHAR(50) NOT NULL DEFAULT 'general',
encrypted_key TEXT NOT NULL,
api_key_hash VARCHAR(64) NOT NULL,
status ENUM('active', 'revoked', 'expired') NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
expires_at DATETIME NULL,
last_used_at DATETIME NULL,
revoked_at DATETIME NULL,
rotated_at DATETIME NULL,
revoke_reason VARCHAR(200) NULL,
usage_count INT DEFAULT 0,
rotation_count INT DEFAULT 0,
INDEX idx_status (status),
INDEX idx_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 审计日志表
CREATE TABLE IF NOT EXISTS audit_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
action VARCHAR(50) NOT NULL,
details TEXT NULL,
user_name VARCHAR(50) NULL,
ip_address VARCHAR(45) NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_action (action),
INDEX idx_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 密钥使用历史表
CREATE TABLE IF NOT EXISTS key_usage_history (
id INT AUTO_INCREMENT PRIMARY KEY,
key_id VARCHAR(32) NOT NULL,
user_agent VARCHAR(255) NULL,
request_count INT DEFAULT 0,
last_accessed_at DATETIME NULL,
FOREIGN KEY (key_id) REFERENCES keys_registry(key_id),
INDEX idx_key_id (key_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
API接口 (public/index.php)
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
require_once '../src/KeyManager.php';
$keyManager = new KeyManager();
$method = $_SERVER['REQUEST_METHOD'];
$path = $_SERVER['PATH_INFO'] ?? '/';
// 简单路由
try {
switch ($method) {
case 'POST':
$action = $_GET['action'] ?? 'generate';
if ($action === 'generate') {
$data = json_decode(file_get_contents('php://input'), true);
$result = $keyManager->generateKey(
$data['name'] ?? 'default_key',
$data['type'] ?? 'general',
$data['expiry_days'] ?? null
);
echo json_encode(['success' => true, 'data' => $result]);
} else {
// 其他POST操作
}
break;
case 'GET':
$apiKey = $_GET['api_key'] ?? null;
if ($apiKey) {
$result = $keyManager->getKey($apiKey);
echo json_encode(['success' => true, 'data' => $result]);
} else {
$keys = $keyManager->listKeys($_GET['status'] ?? null);
echo json_encode(['success' => true, 'data' => $keys]);
}
break;
case 'DELETE':
$keyId = $_GET['key_id'] ?? null;
$result = $keyManager->revokeKey($keyId);
echo json_encode(['success' => true, 'message' => 'Key revoked']);
break;
default:
http_response_code(405);
echo json_encode(['success' => false, 'error' => 'Method not allowed']);
}
} catch (Exception $e) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
README文件 (README.md)
# PHP Key Management System 一个简单但功能完整的密钥管理系统。 ## 功能特点 - ✅ 安全生成加密密钥 - ✅ 使用AES-256加密存储密钥 - ✅ 支持密钥轮换和撤销 - ✅ 完整的审计日志 - ✅ 密钥过期管理 - ✅ RESTful API接口 ## 安装指南 1. 导入数据库schema: ```bash mysql -u root -p < sql/schema.sql
-
设置主密钥环境变量:
export MASTER_KEY='your_very_secret_master_key'
-
配置数据库连接: 编辑
config/config.php -
启动服务:
php -S localhost:8000 -t public/
API使用示例
生成新密钥
curl -X POST "http://localhost:8000/?action=generate" \
-H "Content-Type: application/json" \
-d '{"name": "my-app-key", "type": "general"}'
获取密钥
curl "http://localhost:8000/?api_key=your_generated_api_key"
轮换密钥
curl -X PUT "http://localhost:8000/?action=rotate&key_id=your_key_id"
撤销密钥
curl -X DELETE "http://localhost:8000/?key_id=your_key_id"
安全注意事项
- 主密钥安全: 主密钥应存储在安全的环境中,不应硬编码在代码中
- 使用HTTPS: 生产环境应使用HTTPS
- 限制访问权限: 仅授权用户可访问API
- 定期轮换: 建议定期轮换密钥
- 监控审计日志: 定期检查审计日志以发现异常
扩展建议
- 添加用户认证和授权
- 实现密钥备份和恢复
- 添加密钥使用统计分析
- 实现自动密钥轮换
- 添加Web界面
使用说明
-
设置环境变量:
export MASTER_KEY='your-secure-master-key'
-
初始化数据库:导入schema.sql
-
生成密钥:调用API生成新密钥
-
使用密钥:通过API获取使用密钥
-
监控管理:查看审计日志和密钥状态
这个系统提供了基本的密钥管理功能,包括生成、存储、加密、轮换和审计,您可以根据需要扩展功能,如添加多用户支持、更强的身份验证机制等。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播