您在使用服务时,可通过 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
示例:
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/jsonHost: ivc.myqcloud.com
计算得到 HeaderList 为
content-type;host
,HttpHeaders 为 content-type=application/json&host=ivc.myqcloud.com
。生成 HttpString
根据 HTTP 方法、HTTP 请求路径、HttpParameters 和 HttpHeaders 生成 HttpString,格式为
HttpMethod\\nUriPathname\\nHttpParameters\\nHttpHeaders\\n
。
其中:HttpMethod 转换为小写,如
get
或 put
;UriPathname 为请求路径,如 /
或 /jobs
;\\n 为换行符;如果其中有字符串为空,前后的换行符需要保留,如 get\\n/jobs\\n\\n\\n
。生成 StringToSign
根据 KeyTime 和 HttpString 生成 StringToSign,格式为
sha1\\nKeyTime\\nSHA1(HttpString)\\n
。
其中:SHA1(HttpString) 为使用 SHA1 对 HttpString 计算的消息摘要。生成 Signature
生成签名
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=****************************************
注意
上述格式中的换行仅用于更好的阅读,实际格式并不包含换行。
签名使用
通过 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]\\nStringToSign = sha1\\nKeyTime\\nSHA1(HttpString)\\nSignature = 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 hmacimport hashlibsha1 = 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.Newh = hmac.New(hashFunc, []byte("YourSecretKey"))h.Write([]byte("ExampleKeyTime"))signKey := h.Sum(nil)
实际案例
准备工作
APPID | SecretId | SecretKey |
1250000000 | ******************** | ******************** |
获取设备列表
原始请求
GET /ivc/urm/resource/getUserResources?OrganizationId=0&PageNumber=1&PageSize=20 HTTP/1.1Date: Thu, 15 Dec 2022 01:43:56 GMTHost: 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.1Date: Thu, 15 Dec 2022 01:43:56 GMTHost: ivc.myqcloud.comAuthorization: q-sign-algorithm=sha1&q-ak=************************************&q-sign-time=1671038349;1671041949&q-key-time=1671038349;1671041949&q-header-list=host&q-url-param-list=organizationid;pagenumber;pagesize&q-signature=****************************************
新增设备
原始请求
POST /ivc/cms/device/add HTTP/1.1Date: Thu, 15 Dec 2022 01:43:56 GMTHost: 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.1Date: Thu, 15 Dec 2022 01:43:56 GMTHost: ivc.myqcloud.comContent-Type: application/jsonAuthorization: q-sign-algorithm=sha1&q-ak=************************************&q-sign-time=1671039836;1671043436&q-key-time=1671039836;1671043436&q-header-list=content-type;host&q-url-param-list=&q-signature=****************************************