报文签名和签名验证
为了防止中间人攻击,确保数据传输的完整性和安全性,报文发送者必须对请求报文进行签名,而报文接收者必须验证这些签名。
报文签名与验签方法:使用请求头中Access-Key
对应的Secret-Key
进行签名和验证签名。
报文签名
ZOLOZ服务强制验证每条请求报文的签名,因此商户在发送请求时,必须正确地对请求报文进行签名。
构建待签名内容
待签名内容是由多个元素组成的字符串,以下是商户待签名内容字符串的构建格式:
copy
<Request Method> <Request URI>
<Client ID>.<Request Time>.<Request Body>
商户在构建请求报文的待签名内容时,需按照以下顺序连接各元素字符串:
- 请求方法
- 空格符 (" ")
- 请求URI
- 换行符 ("\n")
- 客户端ID
- 点字符 (".")
- 设置Request-Time字段的请求时间
- 点字符 (".")
- 请求正文
以下是商户待签名内容字符串的示例:
copy
POST /api/v1/zoloz/authentication/test
2089012345678900.2020-01-01T08:00:00+0800.{
"title": "hello",
"description": "just for demonstration."
}
计算签名
- 解码Base64密钥。
使用支持URL安全字符集(即使用-
替换+
,_
替换/
)的标准Base64解码函数,将secretKey
从Base64编码转换为原始字节数据。
注意:部分语言默认的Base64解码器可能不支持URL安全字符,此时需手动替换或使用专用库。 - 初始化HMAC-SHA256。
- 创建HMAC-SHA256实例。
- 将解码后的字节数组作为密钥传入,初始化HMAC-SHA256算法。
注意:密钥类型需要为字节流(byte[]
),不支持字符串。
- 计算签名。
- 将待签名字符串以UTF-8编码转换为字节数组。
- 使用HMAC-SHA256算法对字节数组进行签名计算,以生成签名结果。
- 编码签名结果。
使用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>
商户在构建响应报文的待验证内容时,需按照以下顺序连接各元素字符串:
- 请求方法
- 空格符 (" ")
- 请求URI
- 换行符 ("\n")
- 客户端ID
- 点字符 (".")
- 设置Response-Time字段的响应时间
- 点字符 (".")
- 响应正文
以下是一个待验证内容字符串的示例:
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"
}
}
验证签名
检查提取的签名与待验证内容字符串是否匹配。
- 根据返回内容生成待签名字符串,并使用Secret-Key和HMAC-SHA256算法生成签名。
- 将生成的签名与Header中返回的签名进行比对,验证签名是否一致。