报文签名和签名验证

为了防止中间人攻击,确保数据传输的完整性和安全性,报文发送者必须对请求报文进行签名,而报文接收者必须验证这些签名。

报文签名与验签方法:使用请求头中Access-Key对应的Secret-Key进行签名和验证签名。

报文签名

ZOLOZ服务强制验证每条请求报文的签名,因此商户在发送请求时,必须正确地对请求报文进行签名。

构建待签名内容

待签名内容是由多个元素组成的字符串,以下是商户待签名内容字符串的构建格式:

copy
<Request Method> <Request URI>
<Client ID>.<Request Time>.<Request Body>

商户在构建请求报文的待签名内容时,需按照以下顺序连接各元素字符串:

  1. 请求方法
  2. 空格符 (" ")
  3. 请求URI
  4. 换行符 ("\n")
  5. 客户端ID
  6. 点字符 (".")
  7. 设置Request-Time字段的请求时间
  8. 点字符 (".")
  9. 请求正文

以下是商户待签名内容字符串的示例:

copy
POST /api/v1/zoloz/authentication/test
2089012345678900.2020-01-01T08:00:00+0800.{
  "title": "hello",
  "description": "just for demonstration."
}

计算签名

  1. 解码Base64密钥。
    使用支持URL安全字符集(即使用-替换+_替换/)的标准Base64解码函数,将secretKey从Base64编码转换为原始字节数据。
    注意:部分语言默认的Base64解码器可能不支持URL安全字符,此时需手动替换或使用专用库。
  2. 初始化HMAC-SHA256。
    1. 创建HMAC-SHA256实例。
    2. 将解码后的字节数组作为密钥传入,初始化HMAC-SHA256算法。
      注意:密钥类型需要为字节流(byte[]),不支持字符串。
  1. 计算签名。
    1. 将待签名字符串以UTF-8编码转换为字节数组。
    2. 使用HMAC-SHA256算法对字节数组进行签名计算,以生成签名结果。
  1. 编码签名结果。
    使用Base64编码函数对签名结果进行编码,将签名结果转换为URL安全的Base64字符串。请确保输出内容符合URL安全格式:
    • 替换Base64字符中的+-/_
    • 删除末尾的填充字符=

以下是计算签名的伪代码:

copy
// Step 1: 解码密钥
keyBytes = base64UrlDecode(secretKey)

// Step 2: 初始化 HMAC-SHA256
hmac = HMAC_SHA256(keyBytes)

// Step 3: 计算签名
signatureBytes = hmac.sign(data.encode("UTF-8"))

// Step 4: 编码结果
signature = base64UrlEncode(signatureBytes).rstrip('=')
  • HMAC-SHA256是国际通用的密码学哈希算法,遵循RFC 2104标准。
  • Base64 URL编码需遵循RFC 4648标准。

签名验证

构建待验证内容

待验证内容是由多个元素组成的字符串,以下是商户待验证内容字符串的构建格式:

copy
<Request Method> <Request URI>
<Client ID>.<Response Time>.<Response Body>

商户在构建响应报文的待验证内容时,需按照以下顺序连接各元素字符串:

  1. 请求方法
  2. 空格符 (" ")
  3. 请求URI
  4. 换行符 ("\n")
  5. 客户端ID
  6. 点字符 (".")
  7. 置Response-Time字段的响应时间
  8. 点字符 (".")
  9. 响应正文

以下是一个待验证内容字符串的示例:

copy
POST /api/v1/zoloz/authentication/test
2089012345678900.2020-01-01T08:00:01+0800.{
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "{\"title\":\"hello\",\"description\":\"just for demonstration.\"}",
    "resultStatus": "S"
 }
}

验证签名

检查提取的签名与待验证内容字符串是否匹配。

  1. 根据返回内容生成待签名字符串,并使用Secret-Key和HMAC-SHA256算法生成签名。
  2. 将生成的签名与Header中返回的签名进行比对,验证签名是否一致。