请求签名

最近更新时间:2020-09-08 10:39:56

准备工作

  1. 获取 SecretId 和 SecretKey。
    请在控制台 云 API 密钥 页面可获取。
  2. 确定开发语言:
    根据不同开发语言,确定对应的 HMAC-SHA1 函数。日志服务 CLS 提供 C#,C++,Go,Java,Node.js,PHP,Python 开发语言的 签名计算 demo 供用户参考。

通过 API 对 CLS 发起的 HTTP 签名请求,使用标准的 HTTP Authorization 头部来传递,如下例所示:

GET /logset?logset_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx HTTP/1.1
Host: ap-shanghai.cls.tencentyun.com
Authorization: q-sign-algorithm=sha1&q-ak=AKIDc9YlmrBcFk4C8sbmXQ8i65XXXXXXXXXX&q-sign-time=1510109254;1510109314&q-key-time=1510109254;1510109314&q-header-list=content-type;host&q-url-param-list=logset_name&q-signature=e8b23b818caf4e33f196f895218bdabdbd1f1423

内外网域名

日志服务请求域名区分内外网形式:

  • 内网域名格式形如${region}.cls.tencentyun.com ,内网域名仅对同地域访问生效,即云服务器或云产品通过内网域名访问相同地域的日志服务。
  • 外网域名格式形如${region}.cls.tencentcs.com,访问源端接入 Internet 网后,正常情况均能访问日志服务外网域名。

region字段是日志服务区域简称,例如北京区域填写ap-beijing,完整区域列表格式参考 地域列表

ap-beijing - 北京
ap-shanghai - 上海
ap-guangzhou - 广州
ap-chengdu - 成都
...

键值描述

请求中的签名内容由多个 key=value 对,通过 “&” 连接而成,格式如下:

q-sign-algorithm=[Algorithm]&q-ak=[SecretId]&q-sign-time=[SignTime]&q-key-time=[KeyTime]&q-header-list=[SignedHeaderList]&q-url-param-list=[SignedParamList]&q-signature=[Signature]

上述组成签名内容的键值(Key=Value)描述如下:

键(Key) 值(Value) 含义
q-sign-algorithm sha1 必需,签名算法,目前仅支持 sha1
q-ak 参数[SecretId] 必需,账户 API 密钥的 SecretId
q-sign-time 参数[SignTime] 必需,签名有效起止时间,Unix 时间戳,以秒为单位,使用;分隔。例如:1510109254;1510109314
q-key-time 参数[KeyTime] 必需,与 q-sign-time 值相同
q-header-list 参数[SignedHeaderList] 必需,需要加入签名的 Http 请求头部的 key,且 key 需转化为小写,并将多个 key 之间以字典顺序排序,例如有多组 key,用;分隔。若不想对任何 header 进行签名,可以写空字符串。
q-url-param-list 参数[SignedParamList] 必需,需要加入签名的 Http 请求 Uri 部分参数,且 key 需转化为小写,并将多个 key 之间以字典顺序排序,如有多组 key,用;分隔。若不想对任何 param 进行签名,可以写空字符串。
q-signature 参数[Signature] 必需,计算出的签名内容,小写字母
注意:

关于 q-sign-time 和 q-key-time, 结束时间要大于起始时间,否则会导致签名马上过期。

计算方法

Signature 计算步骤:

  1. 按照指定格式拼接 HTTP 请求的相关信息为字符串 HttpRequestInfo。
  2. 对 HttpRequestInfo 使用 sha1 算法计算哈希值,与其他指定参数按照指定格式组成签名原串 StringToSign。
  3. 使用 SecretKey 对 q-key-time 进行加密,得到 SignKey。
  4. 使用 SignKey 对 StringToSign 进行加密,生成 Signature。
注意:

特殊字符的 urlencode 结果要使用大写字符,例如/编码为%2F,不能使用%2f

步骤1: 拼接 HttpRequestInfo

HttpRequestInfo 由 HTTP 请求中的 Method,Uri,Headers,Parameters 组成,具体方式如下:

HttpRequestInfo = Method + "\n"
                + Uri + "\n"
                + FormatedParameters + "\n"
                + FormatedHeaders + "\n"

上述中的\n表示换行转义字符,+表示字符串连接操作,其他各个参数定义如下:

字段名 含义
Method HTTP 请求使用的方法,小写字母,例如get、post
Uri HTTP 请求的资源名称,不包含 query string 部分,例如/logset
FormatedParameters HTTP 请求 query string 部分参数序列化的字符串,即 q-url-param-list 中指定的参数,若无指定,则使用空字符串。key 和 value 以=连接,不同键值对以&连接, 需要以字典序排列,key 为小写字母,value 需要做 urlencode
FormatedHeaders HTTP 请求的 header,即 q-header-list 中指定的 HTTP 头部,如无指定,则使用空字符串,key 和 value 以=连接,不同键值对以&连接, 需要以字典序排列,key 为小写字母,value 需要做 urlencode

获取 logset 信息,HTTP 请求如下:

GET /logset?logset_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx HTTP/1.1
Host: ap-shanghai.cls.tencentyun.com

对应的 HttpRequestInfo 如下:

有请求参数:

get\n/logset\nlogset_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\nhost=ap-shanghai.cls.tencentyun.com\n

无请求参数:

get\n/logset\n\nhost=ap-shanghai.cls.tencentyun.com\n
说明:

无参数不能省去\n, 所以生成\n\n

步骤2:拼接 StringToSign

StringToSign 由 q-sign-algorithm,q-sign-time,HttpRequestInfo 的 sha1 哈希值组成,具体方式如下:

StringToSign = q-sign-algorithm + "\n"
             + q-sign-time + "\n"
             + sha1(HttpRequestInfo) + "\n"

上述中的\n表示换行转义字符, +表示字符串连接操作,其他参数上面已经描述过,其中 HttpRequestInfo 的 sha1 哈希值为16进制的小写字符串。

注意:

您需事先将\n转义为换行符,再对 HttpRequestInfo 进行 sha1 计算。

对应的结果如下:

StringToSign = sha1\n1578973108;1578974918\n7be58ef9a64ecca66f96b79dc70d279bd93915cf\n

步骤3: 生成 SignKey

目前,API 只支持一种数字签名算法,即默认签名算法 hmac-sha1。 其伪代码如下:

SignKey = Hexdigest(HMAC-SHA1(q-key-time, SecretKey))

其中HMAC-SHA1为加密算法,Hexdigest为转换为16进制字符串的方法。有些语言的加密算法输出结果直接为16进制字符串,则无需转换。

对应的如下:

SignKey = Hexdigest(HMAC-SHA1(1578973108;1578974918, LUSE4nPK1d4tX5SHyXv6tZXXXXXXXXXX))

步骤4: 生成 Signature

目前,API 只支持一种数字签名算法,即默认签名算法 hmac-sha1。 其伪代码如下:

Signature = Hexdigest(HMAC-SHA1(StringToSign, SignKey))

其中HMAC-SHA1为加密算法,Hexdigest为转换为16进制字符串的方法。有些语言的加密算法输出结果直接为16进制字符串,则无需转换。

对应的签名如下:

Signature = Hexdigest(HMAC-SHA1(sha1\n1578973108;1578974918\n7be58ef9a64ecca66f96b79dc70d279bd93915cf\n, 100edfdb73b873dae3d94665a2a7505258475486))

举例说明

使用如下 SecretId 和 SecretKey 进行签名说明:

SecretId = "AKIDc9YlmrBcFk4C8sbmXQ8i65XXXXXXXXXX"
SecretKey = "LUSE4nPK1d4tX5SHyXv6tZXXXXXXXXXX"

StartTime = 1578976553
EndTime = 1578978363

例一
获取 logset 信息,HTTP 请求如下:

GET /logset?logset_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx HTTP/1.1
Host: ap-shanghai.cls.tencentyun.com
Content-Type: application/json

对如上请求,请求头 Host 如果加入签名则生成的字符串为:

HttpRequestInfo=get\n/logset\nlogset_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\ncontent-type=application%2Fjson&host=ap-shanghai.cls.tencentyun.com\n

根据 HttpRequestInfo 组成签名原串 为:

StringToSign = sha1\n1578976553;1578978363\ne2d0126b61269ef047d9d05b6c385cea0aea9799\n

使用 SecretKey 对 q-key-time 进行加密,得到为:

SignKey = f49255658de17084898d83beaa755b9f0301591f

使用 SignKey 对 StringToSign 进行加密,生成 :

Signature = 315dfa0d0ce55582145f7800df5eb3e9c88d2f84

拼接最后的签名为:

Authorization = q-sign-algorithm=sha1&q-ak=AKIDc9YlmrBcFk4C8sbmXQ8i65XXXXXXXXXX&q-sign-time=1578976553;1578978363&q-key-time=1578976553;1578978363&q-header-list=content-type;host&q-url-param-list=logset_id&q-signature=315dfa0d0ce55582145f7800df5eb3e9c88d2f84

最终的请求内容为:

GET /logset?logset_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx HTTP/1.1
Host: ap-shanghai.cls.tencentyun.com
Content-Type: application/json
Authorization: q-sign-algorithm=sha1&q-ak=AKIDc9YlmrBcFk4C8sbmXQ8i65XXXXXXXXXX&q-sign-time=1578976553;1578978363&q-key-time=1578976553;1578978363&q-header-list=content-type;host&q-url-param-list=logset_id&q-signature=315dfa0d0ce55582145f7800df5eb3e9c88d2f84

例二
修改 logset 信息,HTTP 请求如下:

PUT /logset HTTP/1.1
Host: ap-shanghai.cls.tencentyun.com
Content-Type: application/json
Content-Length: 50

{"logset_id":"xxxx-xx-xx-xx-xxxxxxxx","period":30}

对如上请求,请求头 Host 如果加入签名则生成的字符串为:

HttpRequestInfo = put\n/logset\n\ncontent-type=application%2Fjson&host=ap-shanghai.cls.tencentyun.com\n
说明:

uri 参数为空,所以是为空字符,但是不能省去\n, 所以生成\n\n

根据 sha1(HttpRequestInfo) 组成签名原串为:

StringToSign = sha1\n1578976553;1578978363\ne86af9693f3de2047dd10dbe2898ecaf1df00de0\n

使用 SecretKey 对 q-key-time 进行加密,得到:

SignKey = f49255658de17084898d83beaa755b9f0301591f

使用 SignKey 对 StringToSign 进行加密,生成 :

Signature = 600aeb5e646d385d7dd9da57ba9b2545cadfaa1c

拼接最后的签名为:

Authorization = q-sign-algorithm=sha1&q-ak=AKIDc9YlmrBcFk4C8sbmXQ8i65XXXXXXXXXX&q-sign-time=1578976553;1578978363&q-key-time=1578976553;1578978363&q-header-list=content-type;host&q-url-param-list=&q-signature=600aeb5e646d385d7dd9da57ba9b2545cadfaa1c

最终的请求内容为:

PUT /logset HTTP/1.1
Host: ap-shanghai.cls.tencentyun.com
Content-Type: application/json
Content-Length: 50
Authorization: q-sign-algorithm=sha1&q-ak=AKIDc9YlmrBcFk4C8sbmXQ8i65XXXXXXXXXX&q-sign-time=1578976553;1578978363&q-key-time=1578976553;1578978363&q-header-list=content-type;host&q-url-param-list=&q-signature=600aeb5e646d385d7dd9da57ba9b2545cadfaa1c
{"logset_id":"xxxx-xx-xx-xx-xxxxxxxx","period":30}
目录