Signature Calculation

Last update:2023-02-06 15:35:17

For each request, Cloud VoD will verify the identity through the Authorization Header in the request.

In this section, we will take the example of getting video list from Cloud VoD and show you how to make up an Authorization Header step by step.
The URL of getting video list is:

How to Use

The Authorization is consist of Algorithm, AccessKey Secret, SignedHeaders and Signature. The Algorithm is a fixed value at WS3-HMAC-SHA256, so the Authorization looks as the following:

Credential=<AccessKeyId >/<Date>/<Region>/<Service>/wos_request,

And the overall calculation process goes as following:

  1. Signature = HexEncode(HMAC_SHA256(SecretKey, StringToSign));
  2. Stringtosign = Algorithm + ‘\n’ + Timestamp + ‘\n’ + Hash.SHA256(CanonicalRequest)
  3. CanonicalRequest = Method + ‘\n’ + RequestURI + ‘\n’ + QueryString + ‘\n’ + CanonicalHeaders + ‘\n’ + SignedHeaders + ‘\n’ + HashedRequestPayload
  4. HashedRequestPayload = Lowercase(HexEncode(Hash.SHA256(RequestPayload)))

Recommended Calculation Steps

Task 1: Create a Canonical Request

To begin the signing process, you have to create a string that includes information from your request in a standardized (canonical) format. This ensures that when Cloud VoD receives the request, the service side can calculate the same signature that you calculated.

You should create a canonical request as the following format:

<HTTPMethod> + "\n" +
<RequestURI> + "\n" +
<QueryString> + "\n" +
<CanonicalHeaders> + "\n" +
<SignedHeaders> + "\n" +

In the canonical request:

Field Description
HTTPMethod One of the HTTP methods, for example GET and POST. In the example request, we are using POST method.
RequestURI The URI of the request. For getting video list api, the URI is /vod/videoManage/getVideoList.
QueryString The query string parameters in request URL. For POST request, QueryString is an empty string “”.
As for GET request, QueryString is the string following “?” in request URL. For example, videoName=testVideoName&pageIndex=2&pageSize=5. *
CanonicalHeaders The key and value of Headers that will be used to calculate the signature. You should include at least Headers host and content-type in CanonicalHeaders. It’s also allowed to add customized Headers in CanonicalHeaders for a better authentication.
1. All uppercase letters need to be converted to lowercase and strip the first and last spaces. Then assemble the key and value in the format of key:value\n.
2. If there is more than one Header to be included in CanonicalHeaders, all the key and value of the Headers should be sorted in ASCII asecnding order of the Header key(lowercase).*
SignedHeaders An ASCII ascending order sorted, semicolon-separated list of lowercase request header names. The listed headers must be the same as those listed in CanonicalHeaders.

For example, in the CanonicalHeaders example above, SignedHeaders should be:
HashedRequestPayload The hexadecimal value of the SHA256 hash of the request payload.
For example, when the request is of content-type: application/json, the HashedRequstPayload is:
Lowercase(HexEncode(Hash.SHA256({"videoName":"a","pageSize":"5","pageIndex":"2"})))When the request if of content-type:application/x-www-form-urlencoded, the HashedRequestPayload is:
Lowercase(HexEncode(Hash.SHA256("videoName=a&pageIndex=2&pageSize=5"))) Note: Lowercase(HexEncode(Hash.SHA256(RequestPayload))) is a pseudo-code to caculate HASH of the request payload, then encode to hexadecimal and convert to lowercase.
For GET request, HashedRequestPayload is a hash of empty string, the hash returns the following value:135b13e1b15e3c836eab2ab9196a86e7bcdb7b68da27215175a65b89ade3587e

For this example, the CanonicalRequest is:

content-type:application/json; charset=utf-8

Task 2: Create a String to Sign

The string to sign includes meta information about your request and about the canonical request that you created in Task 1: Create a canonical request for Signature. You will use the string to sign and a derived signing key that you create later as inputs to calculate the request signature in Task 3: Calculate the signature.

The string to sign is a concatenation of the following strings:

StringToSign =
    Algorithm + \n +
    Timestamp + \n +
Field Description
Algorithm Hash algorithm that you are using, currently fixed to “WS3-HMAC-SHA256”.
Timestamp Timestamp in second which matches the value you use in request Header X-WS-Timestamp. For this example, the value is 1564645579.
HashedCanonicalRequest The hash of CanonicalRequest that you created in Task 1: Create a Canonical Request, in this example, it’s 16bc1b4d4e6818f5aec2a7273cb2c3d3e4831fd61c6510222b9bec19bffac646.

Note: You need to ensure that the timestamp and standard time are synchronized, otherwise it will fail if the time difference is more than five minutes. If your system has not synchronized with the standard time for a long time, the request may fail and return an expired signature error due to the timestamp expiration.

For this example, the StringToSign is:


Task 3: Calculate Signature

The signature is the HMAC-SHA256 hash of the string to sign that you make from task 2, usi- ng your accessKey Secret as the key for hash-encode. The calculation method is as follows:

Signature = HMAC-SHA256(SigningKey, StringToSign)

Note: Make sure you specify the HMAC parameters in the correct order for the programming language you are using. This example shows the key as the first parameter and the data (message) as the second parameter, but the function that you use might specify the key and data in a different order.*

Task 4: Create Authorization

The Authorization is the value that you should put in your request Header for authentication. The resulting Authorization can be made as follows:

Authorization =
    Algorithm + ' ' +
    'Credential=' + AccessKey + ', ' +
    'SignedHeaders=' + SignedHeaders + ', ' +
    'Signature=' + Signature
Field Description
Algorithm Hash algorithm that you are using, currently fixed to “WS3-HMAC-SHA256”.
AccessKey The AccessKey ID. you can get the AccessKey ID under Security Settings > Access Control > User Information Management > AccessKey Management on console. In the example, AccessKey ID is AKIDz8krbsJ5yKBZQpn74WFkmLPx3EXAMPLE.
SignedHeaders See more details in Task 1: Create a Canonical Request. In the example, the value is content-type;host.
Signature The signature you created in Task 3: Calculate Signature. In the example, signature value is 72e494ea809ad7a8c8f7a4507b9bddcbaa8e581f516e8da2f66e2c5a96525168.

According to the info above, we can get a Authorization as follows:

WS3-HMAC-SHA256 Credential=AKIDz8krbsJ5yKBZQpn74WFkmLPx3EXAMPLE, SignedHeaders=content-type;host, Signature=792dcb6d648a456a030c9c6683fa7bde2a31cb4c72cfeaa354da000adf7c288d

And the final request is:

Authorization: WS3-HMAC-SHA256 Credential=AKIDz8krbsJ5yKBZQpn74WFkmLPx3EXAMPLE, SignedHeaders=content-type;host, Signature=792dcb6d648a456a030c9c6683fa7bde2a31cb4c72cfeaa354da000adf7c288d
Content-Type: application/json; charset=utf-8
X-WS-AccessKey: AKIDz8krbsJ5yKBZQpn74WFkmLPx3EXAMPLE
X-WS-Timestamp: 1564645579


Error Codes

Code Description
4001 Incorrect authentication parameters, please check if all required parameters are carried in the request.
4002 X-WS-AccessKey error, please check if the accesskey exists in the request.
4003 Incorrect X-WS-Timestamp, the timestamp should be in second level.
4004 X-WS-Timestamp expires.
4005 Incorrect host parameter.
4006 Incorrect content-type.
4007 Authentication failed, please check if the parameters are correct.
4008 Authentication failed. The failure can be Tcaused by the following reasons:
- Incorrect Signature.
- The signature does not match what was actually sent in request.
- Incorrect AccessKey Secret.
4009 The authorization has already been used in another request, please create another one.

curl Example

POST Request


curl -X POST 
-H "Authorization: WS3-HMAC-SHA256 Credential=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, SignedHeaders=content-type;host, Signature=471d8f86cefa4fa2f929642207b6df8fe770e82e0df328f4f68af08c8b8a8029" 
-H "Content-Type: application/json; charset=utf-8" 
-H "Host:" 
-H "X-WS-Timestamp: 1564644606" 
-H "X-WS-AccessKey: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
-d '{"videoName": "a","pageIndex":"2","pageSize":"5"}'


curl -X POST 
-H "Authorization: WS3-HMAC-SHA256 Credential=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, SignedHeaders=content-type;host, Signature=37ea1014de0c90e83e733f8d19a5d3ae993896d34450c9f8cf8df5642c81339e" 
-H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" 
-H "Host:" 
-H "X-WS-Timestamp: 1564644607" 
-H "X-WS-AccessKey: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
-d 'videoName=a&pageIndex=2&pageSize=5'

GET Request

curl -X GET 
-H "Authorization: WS3-HMAC-SHA256 Credential=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, SignedHeaders=content-type;host,     Signature=0b489e43c5cd2e52cbe0768a68c614a4211210a6d63b18ff65cc986f18e75aac" 
-H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" 
-H "Host:" 
-H "X-WS-Timestamp: 1564644607" 
-H "X-WS-AccessKey: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

For GET Requests, the Content-Type must be application/x-www-form-urlencoded.

Is the content of this document helpful to you?
I have suggestion
Submitted successfully! Thank you very much for your feedback, we will continue to strive to do better!