PHP API 接口数据加密传输实现

```html PHP API 接口数据加密传输实现

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 的重要基石。

```