Request Signature

Last updated: 2018-07-06 17:07:44

Tencent Cloud API will verify every access request. Every request needs to contain a signature in common request parameters for identity verification. The signature is generated by your security credential, which include SecretID and SecretKey. If you do not have a security credential, you need to apply for it on Tencent Cloud official website. Otherwise, you cannot call Tencent Cloud APIs.

1. Applying for a Security Credential

Before the first-time use of the cloud API, you need to apply for a security credential on the Tencent Cloud CVM console.
The security credential includes SecretId and SecretKey, where:

SecretId: Used to indicate the API caller identity.

SecretKey: The key used to encrypt the signed string and verify it on the server.

Note: The API key is an important credential to build Tencent Cloud API requests. Any one with is key can get access to your Tencent Cloud resources. For the security of your property and services, please properly save and regularly change the key. Delete the old key in time when you change your key.

Do the followings to apply for a security credential:

1) Log in to the Tencent Cloud Console.

2) Select account name in the top right corner on the navigation bar, and choose "Cloud API Key" in the drop-down box to access the Cloud API key management page.

3) On the Cloud API Key Management page, click "New" to create a pair of SecretId/SecretKey. Each account can have two pairs of SecretId/SecretKey at most.

A developer account can have up to two SecretId/SecretKey pairs.
A QQ account that has been added by the developer as a sub-user can apply for different security credentials on different developer consoles.
The sub-user security credential currently can only call some cloud APIs.

2. Generating a signature

You can generate a signed string after obtaining the SecretId and SecretKey. The following details the procedure for generating a signed string.

Suppose the user's SecretId and SecretKey are:

SecretId: AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA

SecretKey: Gu5t9xGARNpq86cd98joQYCN3Cozk1qA

Note: This is only an example. Please continue the subsequent operations with your own SecretId and SecretKey!
Here we use the DescribeInstances request as an example. When you call this API, the request parameters may be as follows:

Parameter Description Value
Action Method name DescribeInstances
SecretId Key ID AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA
Timestamp Current timestamp 1465185768
Nonce Random positive integer 11886
Region Instance region gz
instanceIds.0 Instance ID to be queried ins-09dx96dg
offset Offset value 0
limit Maximum allowable output 20

According to the above table, only five public request parameters are listed here: Action, SecretId, Timestamp, Nonce and Region, rather than six parameters. In fact, the sixth parameter Signature is generated by other parameters (including the instruction request parameter). The specific steps are as follows:

2.1. Sorting parameters

First of all, sort all request parameters in ascending lexicographic order, which means intuitively they are in the same order as words in the dictionary, according to the order of the alphabet or numeration table: The first letter is considered first, then the second letter, and so on. You can use the relevant sorting function in the programming language, for example, the PHP ksort function, to achieve this feature. The results of sorting the parameters in the above example are as follows:

{
    'Action' : 'DescribeInstances',
    'Nonce' : 11886,
    'Region' : 'gz',
    'SecretId' : 'AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA',
    'Timestamp' : 1465185768,
    'instanceIds.0' : 'ins-09dx96dg',
    'limit' : 20,
    'offset' : 0,
}

When using other programming languages in development, you can also sort the parameters in the above example, as long as the same results are obtained.

2.2. Combining a request string

This step generates a request string.
Format the request parameters sorted in previous step to the form of "Parameter"="Value". For example, for the Action parameter, the name is "Action" and the value "DescribeInstances"; the formatted form is Action=DescribeInstances.
Note: 1. "Value" here is the original value rather than the URL-encoded value. 2. If the input parameter contains an underscore, you need to convert it to ".".

Then combine these parameters in formatted form with the "&" symbol and the resulting request string is:

Action=DescribeInstances&Nonce=11886&Region=gz&SecretId=AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA&Timestamp=1465185768&instanceIds.0=ins-09dx96dg&limit=20&offset=0

2.3. Combining a signed source string

This step generates the original string of a signature.
The signed source string consists of the following parameters:

1) Request mode: POST and GET modes are supported and the GET mode is used here. Note that all letters are uppercase.
2) Request host: The domain name for the DescribeInstances request is cvm.api.qcloud.com. The actual request domain name varies with the module to which the API belongs. For details, refer to the description of each API.
3) Request path: The request path for the cloud API is fixed at /v2/index.php.
4) Request string: It is the request string generated in the previous step.

The combination rule for signed source strings is:

Request method + Request server + Request path + ? + Request string

The combination results in this example are:

GETcvm.api.qcloud.com/v2/index.php?Action=DescribeInstances&Nonce=11886&Region=gz&SecretId=AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA&Timestamp=1465185768&instanceIds.0=ins-09dx96dg&limit=20&offset=0

2.4. Generating a signature

This step generates a signature.
First, the HMAC-SHA1 algorithm is used to complete signature with the signed source string obtained in the previous step, and then the generated signed string is encoded using Base64 to obtain the final signed string.

Specific codes are as follows (the PHP language as an example):

$secretKey = 'Gu5t9xGARNpq86cd98joQYCN3Cozk1qA';
$srcStr = 'GETcvm.api.qcloud.com/v2/index.php?Action=DescribeInstances&Nonce=11886&Region=gz&SecretId=AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA&Timestamp=1465185768&instanceIds.0=ins-09dx96dg&limit=20&offset=0';
$signStr = base64_encode(hash_hmac('sha1', $srcStr, $secretKey, true));
echo $signStr;

The resulting signed string is:

NSI3UqqD99b/UJb4tbG/xZpRW64=

When using other programming languages in development, you can also verify the signed source string in the above example, as long as the same signed string is obtained.

3. Signature encoding

The generated signature cannot be used directly as a request parameter, and URL encoding is required.
If the signature generated in the previous step is NSI3UqqD99b/UJb4tbG/xZpRW64=, then the URL-encoded string is NSI3UqqD99b%2FUJb4tbG%2FxZpRW64%3D. Therefore, the resulting signature request parameter is: NSI3UqqD99b%2FUJb4tbG%2FxZpRW64%3D, which will be used to generate the final request URL.

Note: If you use the GET request mode, then URL encoding is required for all request parameter values. Some language libraries will automatically encode the URL. Duplicate encoding will cause signature verification failure.

4. Authentication failure

When the authentication fails, possible errors are as follows:

Error Code Type Description
4100 Verification failed Signature verification failed, Please ensure that the signature in your request parameters is calculated correctly. Or maybe the key state is incorrect. Make sure that the API key is valid and not disabled.
4101 Not authorized by the developer to access this API The sub-user is not authorized to call this API. Please contact the developer for authorization. For details, refer to Authorization policies.
4102 Not authorized by the developer to access the resources operated by this API The resource parameters that you request contain resources whose access is not authorized by the developer. Please check in the message field for the resource IDs that you do not have permissions to view.
Please contact the developer for authorization. For details, refer to Authorization Policies.
4103 Only the developer SecretId can call this API currently. The sub-user SecretID cannot call this API, and only the developer SecretID can.