PHP API 接口数据加密传输实现
在 Web 开发中,API 接口常需传输敏感数据(如用户令牌、订单信息等)。明文传输存在被窃听、篡改风险。本文介绍一种轻量、安全、可落地的 PHP 加密方案:基于 AES-256-CBC 对称加密 + HMAC-SHA256 签名验证,兼顾安全性与性能。
核心设计原则
- 机密性:使用 AES-256-CBC 加密原始 JSON 数据;
- 完整性:对密文+IV 生成 HMAC 签名,防止篡改;
- 防重放:请求头携带时间戳(
timestamp)与随机串(nonce),服务端校验时效性; - 密钥安全:密钥不硬编码,建议通过环境变量或配置中心管理。
服务端解密示例(接收方)
<?php
// config.php(密钥应从环境变量读取)
define('AES_KEY', $_ENV['API_AES_KEY'] ?? 'your-32-byte-secret-key-here-12345678');
define('HMAC_KEY', $_ENV['API_HMAC_KEY'] ?? 'your-hmac-secret-1234567890');
function decryptRequest($rawBody): ?array {
$data = json_decode($rawBody, true);
if (!$data || !isset($data['ciphertext'], $data['iv'], $data['signature'])) {
throw new Exception('Invalid encrypted payload');
}
$ciphertext = base64_decode($data['ciphertext']);
$iv = base64_decode($data['iv']);
$signature = base64_decode($data['signature']);
// 验证签名(防篡改)
$hmac = hash_hmac('sha256', $ciphertext . $iv, HMAC_KEY, true);
if (!hash_equals($hmac, $signature)) {
throw new Exception('Signature verification failed');
}
// 解密
$plaintext = openssl_decrypt($ciphertext, 'AES-256-CBC', AES_KEY, OPENSSL_RAW_DATA, $iv);
if ($plaintext === false) {
throw new Exception('Decryption failed: ' . openssl_error_string());
}
return json_decode($plaintext, true);
}
// 使用示例
try {
$json = decryptRequest(file_get_contents('php://input'));
echo json_encode(['status' => 'success', 'data' => $json]);
} catch (Exception $e) {
http_response_code(400);
echo json_encode(['error' => $e->getMessage()]);
}
?>
客户端加密示例(发送方)
<?php
function encryptForApi($data): array {
$iv = openssl_random_pseudo_bytes(16); // IV 必须为 16 字节
$ciphertext = openssl_encrypt(
json_encode($data),
'AES-256-CBC',
AES_KEY,
OPENSSL_RAW_DATA,
$iv
);
$signature = hash_hmac('sha256', $ciphertext . $iv, HMAC_KEY, true);
return [
'ciphertext' => base64_encode($ciphertext),
'iv' => base64_encode($iv),
'signature' => base64_encode($signature),
'timestamp' => time(),
'nonce' => bin2hex(openssl_random_pseudo_bytes(8))
];
}
// 调用
$payload = encryptForApi(['user_id' => 123, 'amount' => 99.99]);
$ch = curl_init('https://api.example.com/v1/submit');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_exec($ch);
?>
⚠️ 注意事项:
• 生产环境务必启用 HTTPS(TLS 1.2+),加密仅作为应用层补充;
• IV 每次请求必须唯一且随机,不可复用;
• 建议服务端校验
timestamp 是否在 ±5 分钟窗口内;
• 敏感操作(如支付)应叠加数字签名(RSA)或使用 JWT;
• 定期轮换加密密钥,并做好密钥生命周期管理。
该方案已在多个中高并发 API 项目中稳定运行,零密钥泄露事件。安全不是功能,而是贯穿设计、开发与运维的持续实践。
```