PHP API 接口数据加密传输实现
在构建 Web API 时,保障敏感数据(如用户凭证、订单信息)的安全传输至关重要。单纯依赖 HTTPS 只能防止中间人窃听,但无法阻止重放攻击或客户端篡改请求体。本文介绍一种轻量、实用的 PHP 端对端加密方案:使用 AES-256-CBC 对请求/响应数据加密,并结合时间戳与签名防重放。
✅ 核心设计原则
- 对称加密:服务端与客户端共享密钥(
$secretKey),用于 AES 加解密; - 动态 IV:每次加密生成随机初始化向量,避免相同明文产生相同密文;
- 签名验证:对加密前的原始 JSON 数据 + 时间戳 + 随机 nonce 进行 HMAC-SHA256 签名,确保完整性与来源可信;
- 时效控制:请求头携带
X-Timestamp,服务端拒绝超过 300 秒的请求。
🔐 客户端加密示例(PHP)
<?php
function encryptApiData($data, $secretKey) {
$iv = random_bytes(16); // AES-256-CBC 需要 16 字节 IV
$plaintext = json_encode($data, JSON_UNESCAPED_UNICODE);
$ciphertext = openssl_encrypt($plaintext, 'AES-256-CBC', $secretKey, OPENSSL_RAW_DATA, $iv);
$timestamp = time();
$nonce = bin2hex(random_bytes(8));
$signature = hash_hmac('sha256', $plaintext . $timestamp . $nonce, $secretKey);
return [
'data' => base64_encode($iv . $ciphertext),
'timestamp' => $timestamp,
'nonce' => $nonce,
'signature' => $signature
];
}
// 使用示例
$payload = ['user_id' => 123, 'action' => 'pay', 'amount' => 99.9];
$encrypted = encryptApiData($payload, 'your_32_byte_secret_key_here_12345678');
echo json_encode($encrypted, JSON_PRETTY_PRINT);
?>
🛡️ 服务端解密与校验(API 入口)
<?php
function decryptApiRequest($rawInput, $secretKey) {
$input = json_decode($rawInput, true);
if (!$input || !isset($input['data'], $input['timestamp'], $input['nonce'], $input['signature'])) {
throw new Exception('Invalid request format');
}
// 防重放:时间差 > 300s 拒绝
if (abs(time() - $input['timestamp']) > 300) {
throw new Exception('Request expired');
}
// 验证签名(防止篡改)
$expectedSig = hash_hmac('sha256',
json_encode($input['data'], JSON_UNESCAPED_UNICODE) .
$input['timestamp'] . $input['nonce'],
$secretKey
);
if (!hash_equals($expectedSig, $input['signature'])) {
throw new Exception('Invalid signature');
}
// 解密数据
$decoded = base64_decode($input['data']);
$iv = substr($decoded, 0, 16);
$ciphertext = substr($decoded, 16);
$plaintext = openssl_decrypt($ciphertext, 'AES-256-CBC', $secretKey, OPENSSL_RAW_DATA, $iv);
if ($plaintext === false) {
throw new Exception('Decryption failed');
}
return json_decode($plaintext, true);
}
// 在 API 入口调用
try {
$rawBody = file_get_contents('php://input');
$decrypted = decryptApiRequest($rawBody, 'your_32_byte_secret_key_here_12345678');
echo json_encode(['status' => 'success', 'data' => $decrypted]);
} catch (Exception $e) {
http_response_code(400);
echo json_encode(['error' => $e->getMessage()]);
}
?>
⚠️ 注意事项:密钥必须安全存储(推荐使用环境变量或配置中心),切勿硬编码;生产环境务必启用 HTTPS;可进一步集成 JWT 或 OAuth2 做身份认证增强。
该方案平衡了安全性与开发效率,适用于中小型业务系统。记住:加密不是银弹,需结合 HTTPS、输入校验、速率限制等多层防护,才能真正筑牢 API 安全防线。
```