签名方法

最近更新时间:2024-11-07 10:52:10

腾讯云 API 会对每个访问的请求进行身份验证,即每个请求都需要在公共请求参数中包含签名信息(Signature)以验证用户身份。签名信息由用户所执有的安全凭证生成,安全凭证包括 SecretId 和 SecretKey,若用户还没有安全凭证,则需要在腾讯云官网上自主申请,否则就无法调用云 API 接口。

申请安全凭证

在第一次使用云 API 之前,用户需要在腾讯云 CVM 控制台上申请安全凭证。安全凭证包括 SecretId 和 SecretKey,其中SecretId 是用于标识 API 调用者身份的,而 SecretKey 是用于加密签名字符串和服务器端验证签名字符串的密钥。用户应严格保管其 SecretKey,避免泄露。
申请安全凭证的具体步骤如下:

  1. 登录 腾讯云管理中心控制台
  2. 单击【云产品】,选择【监控与管理】>【访问密钥】,进入管理页面。
  3. 单击【新建密钥】,即可创建一对 SecretId / SecretKey,每个账号最多可以拥有两对 SecretId/SecretKey。
    新建密钥

生成签名串

注意:

  • 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。
  • 以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305。

有了安全凭证 SecretId 和 SecretKey 后,就可以生成签名串了。下面给出了一个生成签名串的详细过程。
假设用户的 SecretId 和 SecretKey 分别是:

  • SecretId:****************************************
  • SecretKey:************************
注意:

本文仅为示例,请您根据自己实际的 SecretId 和 SecretKey 进行后续操作。

查询域名信息(DescribeCdnHosts)请求为例,当用户调用这一接口时,其请求参数可能如下:

参数名称 中文 参数值
Action 方法名 DescribeCdnHosts
SecretId 密钥Id ****************************************
Timestamp 当前时间戳 1463122059
Nonce 随机正整数 13029
offset 偏移量 0
limit 查询输出数目 10

由上表可以看出,请求参数中的公共请求参数只有4个:Action、SecretId、Timestamp、Nonce,而不是在 “公共请求参数” 中所述的6个,事实上,Region 对 CDN 而言不是必填项,而第6个参数 Signature(签名串)正是由其他参数(包括指令请求参数)共同生成的,具体步骤如下:

  1. 对参数排序
    首先对所有请求参数按参数名做字典序升序排列,所谓字典序升序排列,直观上就如同在字典中排列单词一样排序,按照字母表或数字表里递增顺序的排列次序,即先考虑第一个 “字母”,在相同的情况下考虑第二个 “字母”,依此类推。您可以借助编程语言中的相关排序函数来实现这一功能,如 PHP 中的 ksort 函数。上述示例参数的排序结果如下:

    {
        "Action": "DescribeCdnHosts",
        "Nonce": 13029,
        "SecretId": "\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*",
        "Timestamp": 1463122059,
        "limit": 10,
        "offset": 0
    }
    使用其它程序设计语言开发时, 可对上面示例中的参数进行排序,得到的结果一致即可。

  2. 拼接请求字符串
    此步骤生成请求字符串。
    将把上一步排序好的请求参数格式化成“参数名称”=“参数值”的形式,如对 Action 参数,其参数名称为 "Action",参数值为 "DescribeCdnHosts",因此格式化后就为 Action=DescribeCdnHosts。

    注意:

    • “参数值” 为原始值而非 URL 编码后的值。
    • 若输入参数中包含下划线,则需要将其转换为 “.”。

    之后将格式化后的各个参数用"&"拼接在一起,最终生成的请求字符串为:

    Action=DescribeCdnHosts&Nonce=13029&SecretId=\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*&Timestamp=1463122059&limit=10&offset=0

  3. 拼接签名原文字符串
    此步骤生成签名原文字符串。
    签名原文字符串由以下几个参数构成:

    • 请求方法:支持 POST 和 GET 方式, 这里使用 GET 请求, 注意方法为全大写。
    • 请求主机:查看域名信息(DescribeCdnHosts)的请求域名为:cdn.api.qcloud.com。实际的请求域名根据接口所属模块的不同而不同, 详见各接口说明。
    • 请求路径:云 API 的请求路径固定为 /v2/index.php。
    • 请求字符串:即上一步生成的请求字符串。
      签名原文串的拼接规则为:

      请求方法 + 请求主机 +请求路径 + ? + 请求字符串

    若为 GET 请求,示例的拼接结果为:

    GETcdn.api.qcloud.com/v2/index.php?Action=DescribeCdnHosts&Nonce=13029&SecretId=*******************************************&Timestamp=1463122059&limit=10&offset=0
    若为 POST 请求,示例的拼接结果为:
    POSTcdn.api.qcloud.com/v2/index.php?Action=DescribeCdnHosts&Nonce=13029&SecretId=********************************************&Timestamp=1463122059&limit=10&offset=0

  4. 生成签名串
    此步骤生成签名串。
    首先使用 HMAC-SHA1 算法对上一步中获得的签名原文字符串进行签名,然后将生成的签名串使用 Base64 进行编码,即可获得最终的签名串。
    具体代码如下,以 PHP 语言为例:

    $secretKey = '****************************';
    $srcStr = 'GETcdn.api.qcloud.com/v2/index.php?Action=DescribeCdnHosts&Nonce=13029&SecretId=****************************************&Timestamp=1463122059&limit=10&offset=0';
    $signStr = base64_encode(hash_hmac('sha1', $srcStr, $secretKey, true));
    echo $signStr
    最终得到的签名串为:
    bWMMAR1eFGjZ5KWbfxTlBiLiNLc=
    若为 POST 请求,则最终的签名结果为:
    i/KcLp6VaOtUmVtT0dqtLpKJOkg=
    使用其它程序设计语言开发时, 可用上面示例中的原文进行签名验证, 得到的签名串与例子中的一致即可。

签名串编码

生成的签名串并不能直接作为请求参数,需要对其进行 URL 编码。

注意:

如果用户的请求方法是 GET,则对所有请求参数值均需要做 URL 编码。

如上一步生成的签名串为:
bWMMAR1eFGjZ5KWbfxTlBiLiNLc=
则其编码后为:
bWMMAR1eFGjZ5KWbfxTlBiLiNLc%3D
因此,最终得到的签名串请求参数(Signature)为:bWMMAR1eFGjZ5KWbfxTlBiLiNLc%3D,它将用于生成最终的请求 URL。

注意:

部分语言库会自动对URL进行编码,重复编码会导致签名校验失败。