签名方法 v3
为什么要进行签名
1.
签名确保请求是由持有有效访问密钥的人发送的。请参阅控制台 云 API 密钥 页面获取密钥相关信息。
2.
为了防止请求在传输过程中被篡改,腾讯云 API 会使用请求参数来计算请求的哈希值,并将生成的哈希值加密后作为请求的一部分,发送到腾讯云 API 服务器。服务器会使用收到的请求参数以同样的过程计算哈希值,并验证请求中的哈希值。如果请求被篡改,将导致哈希值不一致,腾讯云 API 将拒绝本次请求。
申请安全凭证
签名版本 v3 签名过程
Content-Type: application/x-www-form-urlencoded
协议格式。对于POST方法,目前支持 Content-Type: application/json
以及 Content-Type: multipart/form-data
两种协议格式,json 格式绝大多数接口均支持,multipart 格式只有特定接口支持,此时该接口不能使用 json 格式调用,参考具体业务接口文档说明。推荐使用 POST 请求,因为两者的结果并无差异,但 GET 请求只支持 32 KB 以内的请求包。1.
2.
3.
AKID********************************
和 ********************************
。用户想查看广州区云服务器名为“未命名”的主机状态,只返回一条数据。则请求可能为:
1. 拼接规范请求串
CanonicalRequest =
HTTPRequestMethod + '\n' +
CanonicalURI + '\n' +
CanonicalQueryString + '\n' +
CanonicalHeaders + '\n' +
SignedHeaders + '\n' +
HashedRequestPayload
字段名称 | 解释 |
---|---|
HTTPRequestMethod | HTTP 请求方法(GET、POST )。此示例取值为 POST 。 |
CanonicalURI | URI 参数,API 3.0 固定为正斜杠(/)。 |
CanonicalQueryString | 发起 HTTP 请求 URL 中的查询字符串,对于 POST 请求,固定为空字符串"",对于 GET 请求,则为 URL 中问号(?)后面的字符串内容,例如:Limit=10&Offset=0。 注意:CanonicalQueryString 需要参考 RFC3986 进行 URLEncode 编码(特殊字符编码后需大写字母),字符集 UTF-8。推荐使用编程语言标准库进行编码。 |
CanonicalHeaders | 参与签名的头部信息,至少包含 host 和 content-type 两个头部,也可加入其他头部参与签名以提高自身请求的唯一性和安全性,此示例额外增加了接口名头部。 拼接规则:头部 key 和 value 统一转成小写,并去掉首尾空格,按照 key:value\n 格式拼接;多个头部,按照头部 key(小写)的 ASCII 升序进行拼接。此示例计算结果是 content-type:application/json; charset=utf-8\nhost:cvm.tencentcloudapi.com\nx-tc-action:describeinstances\n 。 注意:content-type 必须和实际发送的相符合,有些编程语言网络库 即使未指定也会自动添加 charset 值,如果签名时和发送时不一致,服务器会返回签名校验失败。 |
SignedHeaders | 参与签名的头部信息,说明此次请求有哪些头部参与了签名,和 CanonicalHeaders 包含的头部内容是一一对应的。content-type 和 host 为必选头部。 拼接规则:头部 key 统一转成小写;多个头部 key(小写)按照 ASCII 升序进行拼接,并且以分号(;)分隔。此示例为 content-type;host;x-tc-action |
HashedRequestPayload | 请求正文(payload,即 body,此示例为 {"Limit": 1, "Filters": [{"Values": ["\u672a\u547d\u540d"], "Name": "instance-name"}]} )的哈希值,计算伪代码为 Lowercase(HexEncode(Hash.SHA256(RequestPayload))),即对 HTTP 请求正文做 SHA256 哈希,然后十六进制编码,最后编码串转换成小写字母。对于 GET 请求,RequestPayload 固定为空字符串。此示例计算结果是 35e9c5b0e3ae67532d3c9f17ead6c90222632e5b1ff7f6e89887f1398934f064 。 |
POST
/
content-type:application/json; charset=utf-8
host:cvm.tencentcloudapi.com
x-tc-action:describeinstances
content-type;host;x-tc-action
35e9c5b0e3ae67532d3c9f17ead6c90222632e5b1ff7f6e89887f1398934f064
2. 拼接待签名字符串
StringToSign =
Algorithm + "\n" +
RequestTimestamp + "\n" +
CredentialScope + "\n" +
HashedCanonicalRequest
字段名称 | 解释 |
---|---|
Algorithm | 签名算法,目前固定为 TC3-HMAC-SHA256 。 |
RequestTimestamp | 请求时间戳,即请求头部的公共参数 X-TC-Timestamp 取值,取当前时间 UNIX 时间戳,精确到秒。此示例取值为 1551113065 。 |
CredentialScope | 凭证范围,格式为 Date/service/tc3_request,包含日期、所请求的服务和终止字符串(tc3_request)。Date 为 UTC 标准时间的日期,取值需要和公共参数 X-TC-Timestamp 换算的 UTC 标准时间日期一致;service 为产品名,必须与调用的产品域名一致。此示例计算结果是 2019-02-25/cvm/tc3_request。 |
HashedCanonicalRequest | 前述步骤拼接所得规范请求串的哈希值,计算伪代码为 Lowercase(HexEncode(Hash.SHA256(CanonicalRequest)))。此示例计算结果是 7019a55be8395899b900fb5564e4200d984910f34794a27cb3fb7d10ff6a1e84 。 |
1.Date 必须从时间戳 X-TC-Timestamp 计算得到,且时区为 UTC+0。如果加入系统本地时区信息,例如东八区,将导致白天和晚上调用成功,但是凌晨时调用必定失败。假设时间戳为 1551113065,在东八区的时间是 2019-02-26 00:44:25,但是计算得到的 Date 取 UTC+0 的日期应为 2019-02-25,而不是 2019-02-26。 2.Timestamp 必须是当前系统时间,且需确保系统时间和标准时间是同步的,如果相差超过五分钟则必定失败。如果长时间不和标准时间同步,可能运行一段时间后,请求失败,返回签名过期错误。
TC3-HMAC-SHA256
1551113065
2019-02-25/cvm/tc3_request
7019a55be8395899b900fb5564e4200d984910f34794a27cb3fb7d10ff6a1e84
3. 计算签名
SecretKey = "********************************"
SecretDate = HMAC_SHA256("TC3" + SecretKey, Date)
SecretService = HMAC_SHA256(SecretDate, Service)
SecretSigning = HMAC_SHA256(SecretService, "tc3_request")
SecretDate
、SecretService
和 SecretSigning
是二进制的数据,可能包含不可打印字符,将其转为十六进制字符串打印的输出分别为:da98fb70dcf6b112dc21038d1eeeb3a95c74b4dcb12c1131f864f6066bd02be0,8d70cbefb03939f929db64d32dc2ba89b1095620119fe3e050e2b18c5bd2752f,b596b923aad85185e2d1f6659d2a062e0a86731226e021e61bfe06f7ed05f5af。字段名称 | 解释 |
---|---|
SecretKey | 原始的 SecretKey,即 ******************************** 。 |
Date | 即 Credential 中的 Date 字段信息。此示例取值为 2019-02-25 。 |
Service | 即 Credential 中的 Service 字段信息。此示例取值为 cvm 。 |
Signature = HexEncode(HMAC_SHA256(SecretSigning, StringToSign))
10b1a37a7301a02ca19a647ad722d5e43b4b3cff309d421d85b46093f6ab6c4f
。4. 拼接 Authorization
Authorization =
Algorithm + ' ' +
'Credential=' + SecretId + '/' + CredentialScope + ', ' +
'SignedHeaders=' + SignedHeaders + ', ' +
'Signature=' + Signature
字段名称 | 解释 |
---|---|
Algorithm | 签名方法,固定为 TC3-HMAC-SHA256 。 |
SecretId | 密钥对中的 SecretId,即 AKID******************************** 。 |
CredentialScope | 见上文,凭证范围。此示例计算结果是 2019-02-25/cvm/tc3_request 。 |
SignedHeaders | 见上文,参与签名的头部信息。此示例取值为 content-type;host;x-tc-action 。 |
Signature | 签名值。此示例计算结果是 10b1a37a7301a02ca19a647ad722d5e43b4b3cff309d421d85b46093f6ab6c4f 。 |
TC3-HMAC-SHA256 Credential=AKID********************************/2019-02-25/cvm/tc3_request, SignedHeaders=content-type;host;x-tc-action, Signature=10b1a37a7301a02ca19a647ad722d5e43b4b3cff309d421d85b46093f6ab6c4f
POST https://cvm.tencentcloudapi.com/
Authorization: TC3-HMAC-SHA256 Credential=AKID********************************/2019-02-25/cvm/tc3_request, SignedHeaders=content-type;host;x-tc-action, Signature=10b1a37a7301a02ca19a647ad722d5e43b4b3cff309d421d85b46093f6ab6c4f
Content-Type: application/json; charset=utf-8
Host: cvm.tencentcloudapi.com
X-TC-Action: DescribeInstances
X-TC-Version: 2017-03-12
X-TC-Timestamp: 1551113065
X-TC-Region: ap-guangzhou
{"Limit": 1, "Filters": [{"Values": ["\u672a\u547d\u540d"], "Name": "instance-name"}]}
注意: 请求发送时的 HTTP 头部(Header)和请求体(Payload)必须和签名计算过程中的内容完全一致,否则会返回签名不一致错误。可以通过打印实际请求内容,网络抓包等方式对比排查。
签名演示
Java
Python
Golang
PHP
Ruby
DotNet
NodeJS
C++
C
其他语言
签名失败
错误码 | 错误描述 |
---|---|
AuthFailure.SignatureExpire | 签名过期。Timestamp 与服务器接收到请求的时间相差不得超过五分钟。 |
AuthFailure.SecretIdNotFound | 密钥不存在。请到控制台查看密钥是否被禁用,是否少复制了字符或者多了字符。 |
AuthFailure.SignatureFailure | 签名错误。可能是签名计算错误,或者签名与实际发送的内容不相符合,也有可能是密钥 SecretKey 错误导致的。 |
AuthFailure.TokenFailure | 临时证书 Token 错误。 |
AuthFailure.InvalidSecretId | 密钥非法(不是云 API 密钥类型)。 |
修改于 2025-03-05 09:31:58