跳到主要内容

签名介绍

我们的签名算法。

推荐使用我们已经封装好的SDK或模块
若您的语言我们已经有提供SDK支持的前提下(PHP、Python、NodeJS、Golang和Java),我们不推荐您重新封装签名。
直接使用 SDK 进行开发,可以帮您省去不少对接的工作量。

自行对接
如果您坚持自行对接签名,我们强烈建议您使用这个调试工具来校对签名:https://www.anquanssl.com/debugtool/

SDK

模块插件

我们提供了一些插件模块,可以帮助您更快地对接我们的产品。

1. 系统参数

系统参数有以下这些:

  • accessKeyId: 请求者的 accessKeyId,申请 API(代理商)权限后由系统分配。
  • timestamp: 时间戳,格式为 YYYY-mm-ddTHH:ii:ssZ,如 2019-10-10T12:00:01Z,特别注意的是需要获取中华人民共和国北京时区下的时间,且误差不能超过 15 分钟。
  • nonce: 幂等 token,格式为英文大小写字母加数字,长度 32 字符内,开发者需要保证在 24 小时内不冲突。
  • sign: 签名,将请求 API 的 URI+系统参数+业务参数排序后做为数据,由 accessKeySecret 进行 sha256 摘要后 base64 得到。具体生成规则请见签名
提示

PHP 代码示例

<?php
$defaultTimeZone = date_default_timezone_get(); //获取签名前的时区
date_default_timezone_set('PRC'); //设置到东八区

$parameters['accessKeyId'] = $this->accessKeyId;
$parameters['nonce'] = uniqid();
$parameters['timestamp'] = date('Y-m-d\TH:i:s\Z'); //获取时间戳
date_default_timezone_set($defaultTimeZone); //还原到签名前的时区

2. 参数整理

首先以业务参数优先,将系统参数合并进业务参数:

提示

PHP 代码示例

<?php
$defaultTimeZone = date_default_timezone_get(); //获取签名前的时区
date_default_timezone_set('PRC'); //设置到东八区

$parameters['accessKeyId'] = $this->accessKeyId;
$parameters['nonce'] = uniqid();
$parameters['timestamp'] = date('Y-m-d\TH:i:s\Z'); //获取时间戳
date_default_timezone_set($defaultTimeZone); //还原到签名前的时区

// 以上是之前的代码
$business_parameters = [/* 业务参数 */];

// 将业务参数中的两头空格移除
function trimize($business_parameters) {
foreach($business_parameters as $key => $value) {
if (is_string($value)) {
// 当 value 为数组时, 需要对 value 下的子项也 trim 操作
$business_parameters[$key] = trim($value);
if ('' === $business_parameters[$key]) {
$business_parameters[$key] = null;
}
} else if (is_array($value)) {
$business_parameters[$key] = trimize($value);
}
}
return $business_parameters;
}
$business_parameters = trimize($business_parameters);

$parameters = array_merge($parameters, isset($arguments[1]) ? $arguments[1] : []);

ksort($parameters);

3. URLEncode 以及 HTTP_Build_Query() 详解

a. URLEncode(键、值均要进行编码):

我们服务器要求对接方对请求参数中出现的以下字符进行替换编码,对于不存在于下面字典的字符(例如中文),可使用语言自带的urlencode函数进行处理:

源字符编码后备注
 +空格
\n%0A回车换行
\r%0D
!%21
"%22
#%23
$%24
%%25
&%26
'%27
(%28
)%29
*%2A
+%2B
,%2C
/%2F
:%3A
;%3B
<%3C
=%3D
>%3E
?%3F
@%40
[%5B
\%5C
]%5D
^%5E
`%60
{%7B
|%7C
}%7D
~%7E

b. HTTP_Build_Query:

例1

{
"accessKeyId": "test_key=",
"timestamp": "2024-04-23T02:50:50Z",
"nonce": "/n241z!"
}

应转换为

accessKeyId=test_key%3D&nonce=%2Fn241z%21&timestamp=2024-04-23T02%3A50%3A50Z

例2

{
"accessKeyId": "test_key=",
"domain_dcv": {
"mydomain.com": "dns",
"*.mydomain.com": "dns",
"bbs.mydomain2.com": "webmaster@mydomain2.com",
},
"timestamp": "2024-04-23T02:50:50Z",
"nonce": "/n241z!"
}

应转换为

accessKeyId=test_key%3D&domain_dcv%5Bbbs.mydomain2.com%5D=webmaster%40mydomain2.com&domain_dcv%5Bmydomain.com%5D=dns&domain_dcv%5B%2A.mydomain2.com%5D=dns&nonce=%2Fn241z%21&timestamp=2024-04-23T02%3A50%3A50Z

4. 签名

将请求的 API 完整相对地址(不带域名部分和?后参数部分),与第二部合并后的所有参数,以 urlencode(key1)=urlencode(value1)&urlencode(key2)=urlencode(value2)的方式拼到一个字串,使用 sha256 以 accessKeySecret 为加密 KEY 签名:

提示

PHP 代码示例

<?php
$defaultTimeZone = date_default_timezone_get(); //获取签名前的时区
date_default_timezone_set('PRC'); //设置到东八区

$parameters['accessKeyId'] = $this->accessKeyId;
$parameters['nonce'] = uniqid();
$parameters['timestamp'] = date('Y-m-d\TH:i:s\Z'); //获取时间戳
date_default_timezone_set($defaultTimeZone); //还原到签名前的时区

$business_parameters = [/* 业务参数 */];
// 将业务参数中的两头空格移除
function trimize($business_parameters) {
foreach($business_parameters as $key => $value) {
if (is_string($value)) {
// 当 value 为数组时, 需要对 value 下的子项也 trim 操作
$business_parameters[$key] = trim($value);
if ('' === $business_parameters[$key]) {
$business_parameters[$key] = null;
}
} else if (is_array($value)) {
$business_parameters[$key] = trimize($value);
}
}
return $business_parameters;
}
$business_parameters = trimize($business_parameters);
$parameters = array_merge($parameters, isset($arguments[1]) ? $arguments[1] : []);

ksort($parameters);
// 以上是之前的代码
$parameters['sign'] = base64_encode(hash_hmac(
'sha256',
$resource . '?' .http_build_query($parameters),
$this->accessKeySecret,
true // 务必选择raw类型,而不要十六进制类型
));

$uri = $this->apiOrigin . $resource;

//接下来可以向 $uri 发起请求了,GET/POST参数就是 $parameters