PHP API 接口数据加密传输实现
在构建 Web API 时,保障敏感数据(如用户凭证、订单信息)的安全传输至关重要。单纯依赖 HTTPS 虽能防窃听,但无法防止重放攻击或中间人篡改请求体。本文介绍一种轻量、实用的 PHP 端对端加密方案:基于 openssl_encrypt() 的 AES-256-CBC 加密 + HMAC 签名验证。
核心设计原则
- 加密:使用 AES-256-CBC 对 JSON 请求体加密,密钥由服务端与客户端共享(建议通过安全信道分发)
- 防篡改:对加密后数据 + 时间戳 + 随机 nonce 计算 HMAC-SHA256 签名
- 防重放:服务端校验时间戳(±5 分钟内有效),并缓存已处理的 nonce
客户端加密示例(PHP)
<?php
function encryptApiPayload($data, $secretKey, $iv) {
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
$cipher = 'AES-256-CBC';
$encrypted = openssl_encrypt($json, $cipher, $secretKey, OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $encrypted . $iv . time(), $secretKey, true);
return [
'encrypted' => base64_encode($encrypted),
'iv' => base64_encode($iv),
'timestamp' => time(),
'nonce' => bin2hex(random_bytes(8)),
'signature' => base64_encode($hmac)
];
}
// 使用示例
$secret = 'your_32_byte_secret_key_123456789012'; // 必须为32字节
$iv = random_bytes(16);
$payload = ['user_id' => 1001, 'amount' => 99.99];
$encryptedReq = encryptApiPayload($payload, $secret, $iv);
echo json_encode($encryptedReq, JSON_PRETTY_PRINT);
?>
服务端解密与验证(PHP)
<?php
function decryptApiPayload($request, $secretKey) {
// 1. 基础校验
if (!isset($request['encrypted'], $request['iv'], $request['timestamp'], $request['nonce'], $request['signature'])) {
throw new Exception('Missing required fields');
}
$encrypted = base64_decode($request['encrypted']);
$iv = base64_decode($request['iv']);
$timestamp = (int)$request['timestamp'];
$nonce = $request['nonce'];
$signature = base64_decode($request['signature']);
// 2. 时间有效性 & 重放防护(需结合 Redis/Memcached)
if (abs(time() - $timestamp) > 300) {
throw new Exception('Request expired');
}
if (isNonceUsed($nonce)) { // 自定义函数:检查 nonce 是否已存在
throw new Exception('Replay attack detected');
}
markNonceAsUsed($nonce, $timestamp); // 缓存 nonce + timestamp
// 3. 签名验证
$expectedHmac = hash_hmac('sha256', $encrypted . $iv . $timestamp, $secretKey, true);
if (!hash_equals($expectedHmac, $signature)) {
throw new Exception('Invalid signature');
}
// 4. 解密
$decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $secretKey, OPENSSL_RAW_DATA, $iv);
if ($decrypted === false) {
throw new Exception('Decryption failed');
}
return json_decode($decrypted, true);
}
// 使用示例(接收 POST JSON)
$input = json_decode(file_get_contents('php://input'), true);
try {
$data = decryptApiPayload($input, 'your_32_byte_secret_key_123456789012');
echo json_encode(['status' => 'success', 'data' => $data]);
} catch (Exception $e) {
http_response_code(400);
echo json_encode(['error' => $e->getMessage()]);
}
?>
安全提示:
• 密钥必须严格保密,禁止硬编码;推荐使用环境变量或密钥管理服务(如 AWS KMS)。
• IV 每次请求必须唯一且随机,不可复用。
• 生产环境务必启用 HTTPS,并配合 CSP、CORS 等策略增强整体安全性。
该方案平衡了安全性与实现成本,适用于中小规模 API 场景。如需更高强度,可升级为非对称加密(RSA/AES 混合)或集成 JWT+Bear Token 方案。安全无小事,加密只是纵深防御中的一环 —— 持续审计、及时更新、最小权限,方为正道。
```