腾讯云 API 会对每个请求进行身份验证,用户使用原生 API 接入需要使用安全凭证,经过特定的步骤对请求进行签名(Signature),每个请求都需要在公共参数中,指定该签名结果并以指定的方式和格式发送请求,以下内容主要介绍 API 接口文档参数以及V3签名方法。
API 文档
公共参数
公共参数是用于标识用户和接口签名的参数,API 接口文档上不会展示公共参数说明,但每次请求 API 均需要携带这些参数,才能正常发起请求。
签名方法
腾讯云支持V1、V3两种签名方式,推荐使用签名方法 V3计算签名,签名方法 V3(或被称为 TC3-HMAC-SHA256)相比签名方法 V1更安全,支持更大的请求包,且 POST JSON 格式,性能有一定提升。

使用签名方法 V3 时,公共参数需要统一放到 HTTP Header 请求头部中,如下表所示:
参数名称 | 类型 | 必选 | 描述 |
Action | String | 是 | HTTP 请求头:X-TC-Action。操作的接口名称,该字段取值为 CreateVideoModerationTask。 |
Region | String | - | HTTP 请求头:X-TC-Region。地域参数,用来标识希望操作哪个地域的数据。取值参考接口文档中输入参数章节关于公共参数 Region 的说明。 注意:某些接口不需要传递该参数,接口文档中会对此特别说明,此时即使传递该参数也不会生效。 |
Timestamp | Integer | 是 | HTTP 请求头:X-TC-Timestamp。当前 UNIX 时间戳,可记录发起 API 请求的时间。例如 1529223702。 注意:如果与服务器时间相差超过5分钟,会引起签名过期错误。 |
Version | String | 是 | HTTP 请求头:X-TC-Version。操作的 API 的版本。取值参考接口文档中入参公共参数 Version 的说明。该字段取值为2020-12-29。 |
Authorization | String | 是 | HTTP 标准身份认证头部字段,例如:
TC3-HMAC-SHA256
Credential
=AKID****/Date/service/tc3_request,
SignedHeaders
=content-type
;host, Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024
其中,TC3-HMAC-SHA256:签名方法,目前固定取该值。 Credential:签名凭证。 AKID**** 是 SecretId;Date 是 UTC 标准时间的日期,取值需要和公共参数 X-TC-Timestamp 换算的 UTC 标准时间日期一致;service 为具体产品名,通常为域名前缀,例如域名 cvm.tencentcloudapi.com 意味着产品名是 cvm。本产品取值为 vm;tc3_request 为固定字符串。 SignedHeaders:参与签名计算的头部信息,content-type 和 host 为必选头部。 Signature:签名摘要,计算过程请参见 签名版本 v3 签名过程。 |
Token | String | 否 | HTTP 请求头:X-TC-Token。即 安全凭证服务 所颁发的临时安全凭证中的 Token,使用时需要将 SecretId 和 SecretKey 的值替换为临时安全凭证中的 TmpSecretId 和 TmpSecretKey。使用长期密钥时不能设置此 Token 字段。 |
Language | String | 否 | HTTP 请求头:X-TC-Language。指定接口返回的语言,仅部分接口支持此参数。 取值:zh-CN,en-US。zh-CN 返回中文,en-US 返回英文。 |
云 API 支持 GET 和 POST 请求。
对于GET方法,只支持
Content-Type: application/x-www-form-urlencoded
协议格式。对于POST方法,目前支持
Content-Type: application/json
协议格式。示例代码
以下为 Java、Go、Python 示例 demo,填写密钥信息、接口入参即可调用,其他语言请参考 签名方法 V3-签名演示,签名演示是云服务器服务作为示例,实际调用时需要根据API接口文档填写参数。
import java.nio.charset.Charset;import java.io.OutputStream;import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;import java.text.SimpleDateFormat;import java.util.Date;import java.util.TimeZone;import java.util.TreeMap;import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import javax.xml.bind.DatatypeConverter;public class CreateVideoModeration {private final static Charset UTF8 = StandardCharsets.UTF_8;private final static String SECRET_ID = "";private final static String SECRET_KEY = "";private final static String CT_JSON = "application/json; charset=utf-8";public static byte[] hmac256(byte[] key, String msg) throws Exception {Mac mac = Mac.getInstance("HmacSHA256");SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());mac.init(secretKeySpec);return mac.doFinal(msg.getBytes(UTF8));}public static String sha256Hex(String s) throws Exception {MessageDigest md = MessageDigest.getInstance("SHA-256");byte[] d = md.digest(s.getBytes(UTF8));return DatatypeConverter.printHexBinary(d).toLowerCase();}public static void main(String[] args) throws Exception {String service = "vm";String host = "vm.tencentcloudapi.com";String region = "ap-guangzhou";String action = "CreateVideoModeration";String version = "2021-09-22";String algorithm = "TC3-HMAC-SHA256";String timestamp = String.valueOf(System.currentTimeMillis() / 1000);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");sdf.setTimeZone(TimeZone.getTimeZone("UTC"));String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));String httpRequestMethod = "POST";String canonicalUri = "/";String canonicalQueryString = "";String canonicalHeaders = "content-type:application/json; charset=utf-8\\n"+ "host:" + host + "\\n" + "x-tc-action:" + action.toLowerCase() + "\\n";String signedHeaders = "content-type;host;x-tc-action";String payload = "{\\"Type\\": \\"xxxx\\",\\"BizType\\": \\"xxxx\\"}";// body数据为jsonString hashedRequestPayload = sha256Hex(payload);String canonicalRequest = httpRequestMethod + "\\n" + canonicalUri + "\\n" + canonicalQueryString + "\\n"+ canonicalHeaders + "\\n" + signedHeaders + "\\n" + hashedRequestPayload;String credentialScope = date + "/" + service + "/" + "tc3_request";String hashedCanonicalRequest = sha256Hex(canonicalRequest);String stringToSign = algorithm + "\\n" + timestamp + "\\n" + credentialScope + "\\n" + hashedCanonicalRequest;byte[] secretDate = hmac256(("TC3" + SECRET_KEY).getBytes(UTF8), date);byte[] secretService = hmac256(secretDate, service);byte[] secretSigning = hmac256(secretService, "tc3_request");String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", "+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;try {URL url = new URL("https://" + host);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("POST");connection.setRequestProperty("Authorization", authorization);connection.setRequestProperty("Content-Type", CT_JSON);connection.setRequestProperty("Host", host);connection.setRequestProperty("X-TC-Action", action);connection.setRequestProperty("X-TC-Timestamp", timestamp);connection.setRequestProperty("X-TC-Version", version);connection.setRequestProperty("X-TC-Region", region);// Enable input/output streams and write the payloadconnection.setDoOutput(true);OutputStream os = connection.getOutputStream();os.write(payload.getBytes(UTF8));os.flush();os.close();// Get the responseint responseCode = connection.getResponseCode();if (responseCode == 200) {BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String inputLine;StringBuilder response = new StringBuilder();while ((inputLine = in.readLine()) != null) {response.append(inputLine);}in.close();// Process the response as neededSystem.out.println("Response: " + response.toString());} else {// Handle the error responseSystem.out.println("Error Response Code: " + responseCode);}connection.disconnect();} catch (Exception e) {e.printStackTrace();}}}
package vmimport ("crypto/hmac""crypto/sha256""encoding/hex""encoding/json""fmt""io/ioutil""net/http""strconv""strings""time")type createmod struct {BizType string `json:"BizType"`Type string `json:"Type"`Tasks []task}type task struct {DataId string `json:"DataId"`Input taskInput `json:"Input"`}type taskInput struct {Type string `json:"Type"`Url string `json:"Url"`}func sha256heCreate(s string) string {b := sha256.Sum256([]byte(s))return hex.EncodeToString(b[:])}func hmacsha256Create(s, key string) string {hashed := hmac.New(sha256.New, []byte(key))hashed.Write([]byte(s))return string(hashed.Sum(nil))}func DetectCreateSingle() {secretId := ""secretKey := ""host := "vm.tencentcloudapi.com"algorithm := "TC3-HMAC-SHA256"service := "vm"version := "2021-09-22"action := "CreateVideoModerationTask"region := "ap-guangzhou"var timestamp int64 = time.Now().Unix()// loc, _ := time.LoadLocation("Asia/Shanghai")// var timestamp int64 = time.Now().In(loc).Unix()// step 1: build canonical request stringhttpRequestMethod := "POST"canonicalURI := "/"canonicalQueryString := ""canonicalHeaders := "content-type:application/json; charset=utf-8\\n" + "host:" + host + "\\n"signedHeaders := "content-type;host"var a = createmod{BizType: "default",Type: "VIDEO",Tasks: []task{{DataId: "123",Input: taskInput{Type: "URL",Url: "", //接口入参},},},}b, err := json.Marshal(a)if err != nil {fmt.Print(err.Error())return}payload := string(b)hashedRequestPayload := sha256heCreate(payload)canonicalRequest := fmt.Sprintf("%s\\n%s\\n%s\\n%s\\n%s\\n%s",httpRequestMethod,canonicalURI,canonicalQueryString,canonicalHeaders,signedHeaders,hashedRequestPayload)// fmt.Println(canonicalRequest)// step 2: build string to signdate := time.Unix(timestamp, 0).UTC().Format("2006-01-02")credentialScope := fmt.Sprintf("%s/%s/tc3_request", date, service)hashedCanonicalRequest := sha256heCreate(canonicalRequest)string2sign := fmt.Sprintf("%s\\n%d\\n%s\\n%s",algorithm,timestamp,credentialScope,hashedCanonicalRequest)// fmt.Println(string2sign)// step 3: sign stringsecretDate := hmacsha256Create(date, "TC3"+secretKey)secretService := hmacsha256Create(service, secretDate)secretSigning := hmacsha256Create("tc3_request", secretService)signature := hex.EncodeToString([]byte(hmacsha256Create(string2sign, secretSigning)))// fmt.Println(signature)// step 4: build authorizationauthorization := fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s",algorithm,secretId,credentialScope,signedHeaders,signature)req, _ := http.NewRequest("POST", "https://"+host, strings.NewReader(payload))req.Header.Set("Authorization", authorization)req.Header.Set("Content-Type", "application/json; charset=utf-8")req.Header.Set("Host", host)req.Header.Set("X-TC-Action", action)req.Header.Set("X-TC-Timestamp", strconv.FormatInt(timestamp, 10))req.Header.Set("X-TC-Version", version)req.Header.Set("X-TC-Region", region)resp, err := (&http.Client{}).Do(req)if err != nil {fmt.Print(err.Error())return}defer resp.Body.Close()respByte, _ := ioutil.ReadAll(resp.Body)fmt.Println(string(respByte))}
#!/usr/bin/env python3# -*- coding: utf-8 -*-import hashlibimport hmacimport jsonimport timeimport datetimeimport requestsfrom concurrent.futures import ThreadPoolExecutorsecret_id = ""secret_key = ""service = "vm"host = "vm.tencentcloudapi.com"endpoint = "https://" + hostregion = "ap-guangzhou"version = "2021-09-22"algorithm = "TC3-HMAC-SHA256"def do_action(action, params):timestamp = int(time.time())# datetime.datetime.utcfromtimestampday = datetime.datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d")# ************* 步骤 1:拼接规范请求串 *************http_request_method = "POST"canonical_uri = "/"canonical_querystring = ""ct = "application/json; charset=utf-8"payload = json.dumps(params)# print(payload)canonical_headers = "content-type:%s\\nhost:%s\\n" % (ct, host)signed_headers = "content-type;host"hashed_request_payload = hashlib.sha256(payload.encode("utf-8")).hexdigest()# print(hashed_request_payload)canonical_request = (http_request_method + "\\n" + canonical_uri + "\\n" +canonical_querystring + "\\n" + canonical_headers +"\\n" + signed_headers + "\\n" + hashed_request_payload)# print(canonical_request)# ************* 步骤 2:拼接待签名字符串 *************credential_scope = day + "/" + service + "/" + "tc3_request"hashed_canonical_request = hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()string_to_sign = (algorithm + "\\n" + str(timestamp) + "\\n" +credential_scope + "\\n" + hashed_canonical_request)# print(string_to_sign)secret_date = sign(("TC3" + secret_key).encode("utf-8"), day)secret_service = sign(secret_date, service)secret_signing = sign(secret_service, "tc3_request")signature = hmac.new(secret_signing, string_to_sign.encode("utf-8"),hashlib.sha256).hexdigest()# print(signature)# ************* 步骤 4:拼接 Authorization *************authorization = (algorithm + " " + "Credential=" + secret_id + "/" +credential_scope + ", " + "SignedHeaders=" +signed_headers + ", " + "Signature=" + signature)# print(authorization)headers = {"Authorization": authorization,"Content-Type": "application/json; charset=utf-8","Host": host,"X-TC-Action": action,"X-TC-Timestamp": str(timestamp),"X-TC-Version": version,"X-TC-Region": region}# time.sleep(15)# 发送请求resp = requests.post(url=endpoint, data=payload, headers=headers)return resp# 计算签名摘要函数def sign(key, msg):return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()def audio_detect(params):action = "CreateVideoModerationTask"resp = do_action(action, params)return resp.textif __name__ == "__main__":params = []video_url = ""p = {"Type":"VIDEO","Tasks": [{"DataId": "default","Name": "测试视频","Input": {"Type": "URL","Url": video_url}}],"BizType":"default"}params.append(p)executor = ThreadPoolExecutor(max_workers=5)resps = executor.map(audio_detect, params)for resp in resps:print(resp)
签名失败
存在以下签名失败的错误码,请根据实际情况处理。
错误码 | 错误描述 |
AuthFailure.SignatureExpire | 签名过期。Timestamp 与服务器接收到请求的时间相差不得超过五分钟。 |
AuthFailure.SecretIdNotFound | |
AuthFailure.SignatureFailure | 签名错误。可能是签名计算错误,或者签名与实际发送的内容不相符合,也有可能是密钥 SecretKey 错误导致的。 |
AuthFailure.TokenFailure | 临时证书 Token 错误。 |
AuthFailure.InvalidSecretId | 密钥非法(不是云 API 密钥类型)。 |