PHP API 接口数据加密传输实现
在构建 Web API 时,保障敏感数据(如用户凭证、订单信息)的安全传输至关重要。单纯依赖 HTTPS 虽能防窃听,但无法防止重放攻击或中间人篡改请求体。本文介绍一种轻量、实用的 PHP 端对端加密方案:使用 AES-256-CBC 对请求/响应 JSON 数据加密,并结合 HMAC 签名与时间戳验证,提升接口安全性。
核心思路
- 客户端:生成随机 IV → AES 加密明文 → 计算 HMAC-SHA256 签名 → 拼装为 JSON 发送
- 服务端:校验时间戳(±5 分钟)→ 验证 HMAC → 解密数据 → 处理业务逻辑
- 密钥(
$secretKey)由前后端安全约定,不通过网络传输
服务端解密与验签示例(PHP)
<?php
function decryptApiRequest($rawBody, $secretKey): ?array {
$data = json_decode($rawBody, true);
if (!$data || !isset($data['iv'], $data['ciphertext'], $data['signature'], $data['timestamp'])) {
return null;
}
// 1. 时间戳防重放(5分钟窗口)
if (abs(time() - (int)$data['timestamp']) > 300) {
return null;
}
// 2. HMAC 验证完整性
$hmac = hash_hmac('sha256', $data['iv'] . $data['ciphertext'] . $data['timestamp'], $secretKey);
if (!hash_equals($hmac, $data['signature'])) {
return null;
}
// 3. AES 解密
$iv = base64_decode($data['iv']);
$ciphertext = base64_decode($data['ciphertext']);
$decrypted = openssl_decrypt($ciphertext, 'AES-256-CBC', $secretKey, OPENSSL_RAW_DATA, $iv);
return $decrypted ? json_decode($decrypted, true) : null;
}
// 使用示例
$secretKey = 'your_32_byte_secret_key_here_12345678'; // 必须为32字节
$requestBody = file_get_contents('php://input');
$payload = decryptApiRequest($requestBody, $secretKey);
if ($payload === null) {
http_response_code(400);
echo json_encode(['error' => 'Invalid or expired request']);
} else {
// ✅ 安全解密成功,处理业务逻辑
echo json_encode(['status' => 'success', 'data' => $payload]);
}
?>
客户端加密参考(JavaScript 简化示意)
前端可使用 crypto-js 或 Web Crypto API 实现对称加密与签名,关键步骤包括:
- 生成 16 字节随机 IV(
CryptoJS.enc.Base64.stringify(CryptoJS.lib.WordArray.random(16))) - AES 加密 JSON 字符串(CBC 模式,PKCS#7 填充)
- HMAC 签名:拼接
iv + ciphertext + timestamp后计算 SHA256 - 最终发送:
{ iv, ciphertext, signature, timestamp }
⚠️ 注意事项:
• 密钥必须严格保密,禁止硬编码于前端;
• 生产环境务必启用 HTTPS;
• 建议配合 API Key、IP 白名单、请求频率限制等多重防护;
• 敏感字段(如密码)仍应在应用层二次哈希,避免仅依赖传输加密。
该方案平衡了安全性与开发效率,适用于中小规模 API 场景。对于金融级系统,建议升级至非对称加密(RSA/AES 混合)或采用 OAuth 2.1 + JWT 标准协议。安全无小事,加密只是纵深防御的第一道门。
```