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

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

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 安全防线。

```