公共请求头与签名规范

ALL APIs 全部开放接口通用通信协议 HMAC-SHA256 强校验

为确保 API 调用的机密性、防篡改与防重放攻击,Dsign Link 开放平台的所有业务接口统一采用 POST 请求协议与 JSON 格式交互,并通过 HTTP 标头传递身份密钥、时间戳、随机数与数字签名。

公共参数适用范围
本文档列出的全部标头均为开放平台公共通信层参数。无论调用文档创建、查询列表、获取签署链接还是文件下载,均须携带此组基础标头。

公共请求头列表 (Common Headers)

Header 名称 类型 是否必填 说明与格式规范
Content-Type string 必填 固定为 application/json; charset=utf-8
X-Api-Access-Key string 必填 开放平台颁发的 API 凭证公钥(Access Key),用于定位调用凭据与租户身份。
X-Api-Timestamp string 必填 十进制 13 位 Unix 毫秒时间戳(如 1789461000000)。服务端校验时钟偏差范围为 ±300 秒(5分钟),超时将被拒绝。
X-Api-Nonce string 必填 每次 HTTP 实际尝试生成的唯一随机字符串(建议使用 16–32 字节密码学随机数 HEX 编码,长度 32–64 字符)。系统在 Redis 中通过原子锁防重放。
X-Api-Signature string 必填 按照规范化规则拼接待签字符串后,使用 Secret Key 计算得出的 Base64 编码 HMAC-SHA256 签名
X-Api-Enterprise-Id string 视凭证类型 目标企业 ID(纯数字字符串):
账号统一密钥(account 模式):必传,指定操作的目标企业。
企业专属密钥(org 模式):已自动绑定所属企业,可省略或传对应一致的企业 ID。
Idempotency-Key string 视接口而定 客户端幂等凭据(16–100 个 ASCII 字符)。在创建文档等写操作接口中为必填,查询类只读接口中可留空。

签名计算规范 (Signature Calculation)

每次请求发起前,调用端必须按照以下确切格式拼接待签名字符串(StringToSign),并使用对应凭证的 SecretKey 进行加密计算:

待签名字符串格式定义 (StringToSign)
StringToSign = UPPERCASE_METHOD + "\n" +
               RAW_PATH + "\n" +
               CANONICAL_QUERY + "\n" +
               RAW_BODY + "\n" +
               TIMESTAMP_MS + "\n" +
               NONCE + "\n" +
               "x-api-enterprise-id:" + X_API_ENTERPRISE_ID + "\n" +
               "idempotency-key:" + IDEMPOTENCY_KEY

Signature = Base64(HMAC-SHA256(SecretKey, UTF8(StringToSign)))
待签名串严格规则说明
  1. UPPERCASE_METHOD:HTTP 请求方法大写,如 POST
  2. RAW_PATH:请求 URI 路径部分,必须以 / 开头,如 /open/documents/create(不包含域名或 query)。
  3. CANONICAL_QUERY:查询参数按 key 字典序升序、value 升序排序并遵循 RFC 3986 百分号编码后以 & 连接。无 query 时为空字符串
  4. RAW_BODY:实际发送的原始请求体 UTF-8 字节内容(SDK 必须先序列化,用同一份原始字符串签名并发送,签名后不可擅自添加格式化换行或空格)。无 body 时为空字符串。
  5. TIMESTAMP_MS:与 X-Api-Timestamp 标头一致的 13 位十进制毫秒时间戳。
  6. NONCE:与 X-Api-Nonce 标头一致的唯一随机数。
  7. x-api-enterprise-id 行:固定为 x-api-enterprise-id: 拼接去空格后的企业 ID,未提供时值为空。
  8. idempotency-key 行:固定为 idempotency-key: 拼接去空格后的幂等键,未提供时值为空。

官方标准契约测试向量 (Test Vector)

开发或验证签名逻辑时,请使用以下测试用例核对实现结果。若输入下列参数计算出的 Signature 与下方结果一致,可作为签名算法实现的核对依据:

契约自检用例 (Contract Self-Test Vector)
SecretKey: sk_test_0123456789
Method: POST
Path: /open/documents
CanonicalQuery: notify=true&tag=a%20b
RawBody: {"title":"测试合同"}
Timestamp: 1789461000000
Nonce: 00112233445566778899aabbccddeeff
X-Api-Enterprise-Id: org_demo
Idempotency-Key: idem_0123456789abcd

[预期计算出的签名 Signature]
iFzS5vOmFdjcL4bj0M34JyhcLZyuFvmTHUGOb+qook0=

统一响应规范 (Unified Response Structure)

全部接口均以 UTF-8 编码的 JSON 数据包返回。每个响应必然携带唯一的 request_id,供系统排查和全链路日志追溯:

{
  "code": 0,
  "message": "success",
  "data": {
    // 具体业务返回结果对象
  },
  "request_id": "req_68dfb7829a10ef4"
}

多语言签名实现示例 (Code Implementation)

推荐直接使用平台提供的各语言官方 SDK。如果自行封装 HTTP 客户端,请参考以下实现逻辑:

function buildSignature(
    string $secretKey,
    string $method,
    string $rawPath,
    string $canonicalQuery,
    string $rawBody,
    string $timestampMs,
    string $nonce,
    string $enterpriseId,
    string $idempotencyKey
): string {
    $stringToSign = strtoupper($method) . "\n"
        . $rawPath . "\n"
        . $canonicalQuery . "\n"
        . $rawBody . "\n"
        . $timestampMs . "\n"
        . $nonce . "\n"
        . "x-api-enterprise-id:" . trim($enterpriseId) . "\n"
        . "idempotency-key:" . trim($idempotencyKey);

    return base64_encode(hash_hmac('sha256', $stringToSign, $secretKey, true));
}