有奖捉虫:云通信与企业服务文档专题,速来> HOT
您在使用服务时,可通过 RESTful API 对服务发起请求,智能视图计算平台通过签名来验证请求的合法性。对于签名请求,我们会进行基于密钥 HMAC(Hash Message Authentication Code)的自定义方案进行身份验证。
说明
所有 API 接口均通过 HTTPS 进行通信,提供高安全性的通信。字符编码均使用 UTF-8 编码。
您可使用 快速签名生成工具临时生成签名或参考签名生成过程(注意:使用时签名类型选择XML API 签名)

准备工作

1. APPID、SecretId 和 SecretKey。 在访问管理控制台的 API 密钥管理 页面中获取。
注意:
SecretId 用于标识 API 调用者身份。
SecretKey 用于加密签名字符串和服务器端验证签名字符串的密钥。
用户必须严格保管安全凭证,避免泄露。
2. 确定开发语言: 支持但不限于 Java、PHP、C#、C++、Node.js、Python,根据不同的开发语言,确定对应的 HMAC-SHA1、SHA1 和 UrlEncode 函数。
其中,HMAC-SHA1 和 SHA1 函数以 UTF-8 编码字符串为输入,以 16 进制小写字符串为输出。UrlEncode 基于 UTF-8 编码,此外对于 ASCII 范围内的可打印字符,下列特殊符号也应被编码:
字符
十进制
十六进制
字符
十进制
十六进制
(空格)
32
20
;
59
3B
!
33
21
<
60
3C
"
34
22
=
61
3D
#
35
23
>
62
3E
$
36
24
?
63
3F
%
37
25
@
64
40
&
38
26
[
91
5B
'
39
27
\\
92
5C
(
40
28
]
93
5D
)
41
29
^
94
5E
*
42
2A
`
96
60
+
43
2B
{
123
7B
,
44
2C
|
124
7C
/
47
2F
}
125
7D
:
58
3A
-
-
-

签名流程

生成 KeyTime

1. 获取当前时间对应的 Unix 时间戳 StartTimestamp,Unix 时间戳是从 UTC(协调世界时,或 GMT 格林威治时间)1970年1月1日0时0分0秒(北京时间 1970年1月1日8时0分0秒)起至现在的总秒数。
2. 根据上述时间戳和期望的签名有效时长算出签名过期时间对应的 Unix 时间戳 EndTimestamp。
3. 拼接签名有效时间,格式为 StartTimestamp;EndTimestamp,即为 KeyTime。 示例:1557902800;1557910000

生成 SignKey

使用 HMAC-SHA1SecretKey 为密钥,以 KeyTime 为消息,计算消息摘要(哈希值),即为 SignKey。
示例:36bcd76dbb8c9f066472fec403df8a34cab34c77

生成 UrlParamList 和 HttpParameters

1. 遍历 HTTP 请求参数,生成 key 到 value 的映射 Map 及 key 的列表 KeyList,其中 key 转换为小写形式,value 使用 UrlEncode 编码。 其中,没有 value 的参数认为 value 为空字符串,如请求路径为 /?OrganizationId,则认为是 /?OrganizationId=
2. 对 KeyList 按照字典序排序。
3. 对 Map 和 KeyList 中的 key 使用 UrlEncode 编码并再次转换为小写形式。
4. 按照 KeyList 的顺序拼接 Map 中的每一个键值对,格式为 key1=value1&key2=value2&key3=value3,即为 HttpParameters。
5. 按照 KeyList 的顺序拼接 KeyList 中的每一项,格式为 key1;key2;key3,即为 UrlParamList。

示例:
示例一: 请求路径:/ivc/urm/resource/getUserResources?OrganizationId=0&PageNumber=1&PageSize=20 UrlParamList: organizationid;pagenumber;pagesize HttpParameters: organizationid=0&pagenumber=1&pagesize=20
注意
请求路径中的请求参数在实际发送请求时也会进行 UrlEncode,因此要注意不要重复执行 UrlEncode。
示例二: 请求路径:/ivc/urm/resource/getUserResources?OrganizationId UrlParamList: organizationid HttpParameters: organizationid=

生成 HeaderList 和 HttpHeaders

生成 HeaderList 和 HttpHeaders 与 生成 UrlParamList 和 HttpParameters 相同,其中用于生成的 HTTP 请求参数替换为 HTTP 请求头,生成的 HttpParameters 即为 HttpHeaders,生成的 UrlParamList 即为 HeaderList。
示例: 请求头:
Content-Type: application/json
Host: ivc.myqcloud.com
计算得到 HeaderList 为 content-type;host,HttpHeaders 为 content-type=application/json&host=ivc.myqcloud.com

生成 HttpString

根据 HTTP 方法、HTTP 请求路径、HttpParametersHttpHeaders 生成 HttpString,格式为 HttpMethod\\nUriPathname\\nHttpParameters\\nHttpHeaders\\n
其中:HttpMethod 转换为小写,如 getput;UriPathname 为请求路径,如 //jobs;\\n 为换行符;如果其中有字符串为空,前后的换行符需要保留,如 get\\n/jobs\\n\\n\\n

生成 StringToSign

根据 KeyTimeHttpString 生成 StringToSign,格式为 sha1\\nKeyTime\\nSHA1(HttpString)\\n。 其中:SHA1(HttpString) 为使用 SHA1HttpString 计算的消息摘要。

生成 Signature

使用 HMAC-SHA1SignKey 为密钥,以 StringToSign 为消息,计算消息摘要,即为 Signature。

生成签名

根据 SecretIdKeyTimeHeaderListUrlParamListSignature 生成签名,格式为:
q-sign-algorithm=sha1
&q-ak=SecretId
&q-sign-time=KeyTime
&q-key-time=KeyTime
&q-header-list=HeaderList
&q-url-param-list=UrlParamList
&q-signature=Signature
注意
上述格式中的换行仅用于更好的阅读,实际格式并不包含换行。

签名使用

通过 RESTful API 发起的 HTTP 签名请求,可以通过以下几种方式传递签名:
1. 通过标准的 HTTP Authorization 头,如 Authorization: q-sign-algorithm=sha1&q-ak=...&q-sign-time=1557989753;1557996953&...&q-signature=...
说明
上述示例中使用 ... 省略了部分具体签名内容。

代码示例

伪代码

KeyTime = [Now];[Expires]
SignKey = HMAC-SHA1([SecretKey], KeyTime)
HttpString = [HttpMethod]\\n[HttpURI]\\n[HttpParameters]\\n[HttpHeaders]\\n
StringToSign = sha1\\nKeyTime\\nSHA1(HttpString)\\n
Signature = HMAC-SHA1(SignKey, StringToSign)

消息摘要算法示例

不同语言如何调用 HMAC-SHA1 可以参考下面的示例:

PHP

$sha1HttpString = sha1('ExampleHttpString');

$signKey = hash_hmac('sha1', 'ExampleKeyTime', 'YourSecretKey');

Java

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.HmacUtils;

String sha1HttpString = DigestUtils.sha1Hex("ExampleHttpString");

String signKey = HmacUtils.hmacSha1Hex("YourSecretKey", "ExampleKeyTime");

Python

import hmac
import hashlib

sha1 = hashlib.sha1()
sha1_http_string = sha1.update('ExampleHttpString'.encode('utf-8')).hexdigest()

sign_key = hmac.new('YourSecretKey'.encode('utf-8'), 'ExampleKeyTime'.encode('utf-8'), hashlib.sha1).hexdigest()

Node.js

var crypto = require('crypto');

var sha1HttpString = crypto.createHash('sha1').update('ExampleHttpString').digest('hex');
var signKey = crypto.createHmac('sha1', 'YourSecretKey').update('ExampleKeyTime').digest('hex');

Go

import (
"crypto/hmac"
"crypto/sha1"
)

h := sha1.New()
h.Write([]byte("ExampleHttpString"))
sha1HttpString := h.Sum(nil)

var hashFunc = sha1.New
h = hmac.New(hashFunc, []byte("YourSecretKey"))
h.Write([]byte("ExampleKeyTime"))
signKey := h.Sum(nil)

实际案例

准备工作

登录访问管理控制台的 API 密钥管理 页面获取其 APPID、SecretId 和 SecretKey,举例如下:
APPID
SecretId
SecretKey
1250000000
AKIDQjz3ltompVjBni5LitkWHF**********
BQYIM75p8x0iWVFSIgqEKw**********

获取设备列表

原始请求

GET /ivc/urm/resource/getUserResources?OrganizationId=0&PageNumber=1&PageSize=20 HTTP/1.1
Date: Thu, 15 Dec 2022 01:43:56 GMT
Host: ivc.myqcloud.com

中间变量

KeyTime = 1671038349;1671041949
SignKey = 003e121ce6c3862a770c74eab3b13d90935104aa
UrlParamList = organizationid;pagenumber;pagesize
HttpParameters = organizationid=0&pagenumber=1&pagesize=20
HeaderList = host
HttpHeaders = host=ivc.myqcloud.com
HttpString = get\\n/ivc/urm/resource/getUserResources\\norganizationid=0&pagenumber=1&pagesize=20\\nhost=ivc.myqcloud.com\\n
StringToSign = sha1\\n1671038349;1671041949\\n2cc1a7b1fa5b6c7ca3d2e0f70f46c6f7c96cb175\\n
Signature = 8d9a6c73ff78900b3875a78df2b63790644b8c3d
其中,(empty string) 代表长度为 0 的空字符串,\\n 代表换行符。

签名后的请求

GET /ivc/urm/resource/getUserResources?OrganizationId=0&PageNumber=1&PageSize=20 HTTP/1.1
Date: Thu, 15 Dec 2022 01:43:56 GMT
Host: ivc.myqcloud.com
Authorization: q-sign-algorithm=sha1&q-ak=AKIDQjz3ltompVjBni5LitkWHF**********&q-sign-time=1671038349;1671041949&q-key-time=1671038349;1671041949&q-header-list=host&q-url-param-list=organizationid;pagenumber;pagesize&q-signature=7731e2dabc8c9238a38a15945617ae17533043f5


新增设备

原始请求

POST /ivc/cms/device/add HTTP/1.1
Date: Thu, 15 Dec 2022 01:43:56 GMT
Host: ivc.myqcloud.com

中间变量

KeyTime = 1671039836;1671043436
SignKey = 82f0e7ee09b1070dc6f3a37c41b01bc2eaf43ced
UrlParamList = (empty string)
HttpParameters = (empty string)
HeaderList = content-type;host
HttpHeaders = content-type=application/json&host=ivc.myqcloud.com
HttpString = post\\n/ivc/cms/device/add\\n\\ncontent-type=application/json&host=ivc.myqcloud.com\\n
StringToSign = sha1\\n1671039836;1671043436\\nd5c37ed1e8f7fd51d14853f8e9e81869f32fdc54\\n
Signature = 2fab8f7909236046e789b4ea483330ec6df91331
其中,\\n 代表换行符。

签名后的请求

POST /ivc/cms/device/add HTTP/1.1
Date: Thu, 15 Dec 2022 01:43:56 GMT
Host: ivc.myqcloud.com
Content-Type: application/json
Authorization: q-sign-algorithm=sha1&q-ak=AKIDQjz3ltompVjBni5LitkWHF**********&q-sign-time=1671039836;1671043436&q-key-time=1671039836;1671043436&q-header-list=content-type;host&q-url-param-list=&q-signature=2fab8f7909236046e789b4ea483330ec6df91331