PHP API 接口数据加密传输实现
在 Web 开发中,API 接口常需传输敏感数据(如用户令牌、订单信息等)。明文传输存在被窃听、篡改风险。本文介绍一种轻量、安全、可落地的 PHP 加密方案:基于 AES-256-CBC 对称加密 + HMAC-SHA256 签名验证,兼顾安全性与性能。
核心设计原则
- 机密性:使用 AES-256-CBC 加密原始 JSON 数据;
- 完整性:对密文+时间戳生成 HMAC 签名,防篡改;
- 时效性:请求携带
timestamp,服务端校验 5 分钟内有效; - 密钥管理:加解密密钥(
$secretKey)与签名密钥($signKey)分离,且不硬编码于代码中。
服务端加密示例(发送方)
<?php
function encryptApiData(array $data, string $secretKey, string $signKey): array
{
$iv = random_bytes(16); // 16字节 IV
$plaintext = json_encode($data, JSON_UNESCAPED_UNICODE);
$ciphertext = openssl_encrypt($plaintext, 'AES-256-CBC', $secretKey, OPENSSL_RAW_DATA, $iv);
$timestamp = time();
$signature = hash_hmac('sha256', $ciphertext . $iv . $timestamp, $signKey);
return [
'data' => base64_encode($ciphertext),
'iv' => base64_encode($iv),
'ts' => $timestamp,
'sign' => $signature
];
}
// 使用示例
$payload = ['user_id' => 123, 'amount' => 99.99, 'currency' => 'CNY'];
$result = encryptApiData($payload, 'your_32_byte_secret_key_here', 'your_sign_key');
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
?>
服务端解密验证(接收方)
<?php
function decryptApiData(array $request, string $secretKey, string $signKey): ?array
{
if (!isset($request['data'], $request['iv'], $request['ts'], $request['sign'])) {
return null;
}
$timestamp = (int)$request['ts'];
if (abs(time() - $timestamp) > 300) { // 超过5分钟失效
return null;
}
$ciphertext = base64_decode($request['data']);
$iv = base64_decode($request['iv']);
$expectedSign = hash_hmac('sha256', $ciphertext . $iv . $timestamp, $signKey);
if (!hash_equals($expectedSign, $request['sign'])) {
return null; // 签名不匹配
}
$plaintext = openssl_decrypt($ciphertext, 'AES-256-CBC', $secretKey, OPENSSL_RAW_DATA, $iv);
return $plaintext ? json_decode($plaintext, true) : null;
}
// 使用示例(如在 Laravel 控制器或原生入口中)
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$data = decryptApiData($input, 'your_32_byte_secret_key_here', 'your_sign_key');
if ($data === null) {
http_response_code(400);
echo json_encode(['error' => 'Invalid or expired request']);
exit;
}
var_dump($data); // ['user_id' => 123, ...]
?>
安全提示:
• 密钥必须通过环境变量(如
$_ENV['API_SECRET_KEY'])注入,禁止写死;
• 生产环境务必启用 HTTPS,防止密文在传输层被截获;
• 可进一步增加 nonce(一次性随机数)防重放攻击;
• 建议配合 JWT 或 OAuth2 实现身份认证,加密仅解决信道安全。
该方案已在多个高并发 API 场景中稳定运行,无额外依赖,兼容 PHP 7.2+。记住:加密不是万能的,但它是构建可信 API 的重要基石。
```