You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

REST API数字签名实现疑难:API密钥格式与验证问题

带数字签名的REST API实现问题:密钥类型与验证困惑

我正在实现一个带数字签名的极简REST API,后端采用PHP开发,客户端使用Python。原本误以为核心逻辑是发送方用私钥通过HMAC对载荷签名,接收方用公钥验证,但落地实现时遇到了密钥相关的问题。

PHP端验证逻辑

public function verify_request(Request $request)
{
    $method = $request->method();
    $timestamp = $request->header("timestamp");
    $public_key = $request->header("api-key");
    $signature = $request->header("signature");
    $url = $request->fullUrl();

    $data = $method.$timestamp.$url;

    $result = openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA256);
    Logger::info("Result : ".$result);
    return $result;
}

曾成功对接其他API的Python客户端代码

import requests
import hashlib
import hmac
import time

public_key = ""
private_key = ""

method = "GET"
base_url = "https://testing-api.com"
endpoint = "/private/test"
url = base_url + endpoint
timestamp = str(int(time.time()))

signature_data = method + timestamp + url

signature = hmac.new(private_key.encode("utf-8"), signature_data.encode("utf-8"), hashlib.sha256).hexdigest()

headers = {
    "api-key": public_key,
    "timestamp": timestamp,
    "signature": signature,
}

response = requests.request(method, url, headers=headers)
print(response)

遇到的密钥相关问题

1. RSA多行密钥的请求头报错

我生成的RSA密钥为多行格式:

public_key = """-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7Jz6mHX1cau3wlc6QrGW+kcVHO0HPj
iwUDxdM1B8KSLgkfle4+Snq6HhOp5VXdQXZkYF4u9ctWbx/sB2oiD1sCAwEAAQ==
-----END PUBLIC KEY-----"""

private_key = """-----BEGIN PRIVATE KEY-----
MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAvsnPqYdfVxq7fCVz
pCsZb6RxUc7Qc+OLBQPF0zUHwpIuCR+V7j5KeroeE6nlVd1BdmRgXi71y1ZvH+wH
aiIPWwIDAQABAkAnxyvkzLS0FH7Cg4x4zgOfo0l9JQGRJ//0K7UzM/tKNZOy881O
+qEDld7XMaUOmyGd/FxSskrJrzWTSqEZtQ8BAiEA7wsKUjGWFyTfuMkj/3/E0XI2
YYEaTRpROl4NN6FUttcCIQDMUnn7JDovxYlp17QhyOb41qc1I402QZ6zNiz33ytP
HQIgA2rr/drZo4ESdcjia9++x6PTZTd8Ucfji2sW00nKNUcCIFo7Oh9Mml2qcMrL
NYOOA2J0+RaggqYpSHqAPE+iwK+JAiB2YbMutRh5EDyTcI2ql/hYFLlAJVT/E1AN
/ItM1KCQQQ==
-----END PRIVATE KEY-----"""

将其放入请求头时触发错误:

requests.exceptions.InvalidHeader: Invalid return character or leading space in header: api-key

2. 短字符串密钥的PHP验证报错

其他API使用的是短字符串格式密钥:

public_key = "Tub3FH4CLjHezvRcSKdeE18a9VrtzL"
private_key = "tBssW3InKRq09OMLkveyuZ65LDRokjVX8FXO0CL5VpdaV73NWayUvJSSAtCs"

但用这类密钥在我的PHP验证逻辑中会报错:

ErrorException: openssl_verify(): supplied key param cannot be coerced into a public key

核心问题

  • 这类使用短字符串格式密钥的API,采用的是什么密钥类型?
  • 为什么这类短字符串密钥无法被openssl_verify识别为有效公钥?

补充说明

后来纠正了之前的误解:这类API并非使用非对称密钥(RSA),而是使用两个独立的对称密钥——一个作为api-key用于身份标识,另一个作为签名密钥,通过HMAC算法生成签名。

内容的提问来源于stack exchange,提问作者Arkaik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:59:53