Signature Calculation

最終更新日:2022-04-15 17:09:14

Overview

You can include the Authorization header in an HTTP request to carry signature information and indicate that the requester is authorized.

In the header, the signature is carried in the authorization header of the HTTP message. The format of Authorization is as follows:

Authorization:WOS-HMAC-SHA256
Credential=<AccessKeyId >/<Date>/<Region>/<Service>/wos_request,
SignedHeaders=<SignedHeader>;<SignedHeader>;<SignedHeader>,
Signature=<Signature>

Note: Line breaks are added to this example just for readability.

The following table is a description of the fields included in Authorization:

Parameter Description
WOS-HMAC-SHA256 Fixed value. The algorithm that is used to calculate the signature. The signing algorithm is HMAC-SHA256.
Credential Your access key ID and the scope information, which includes the date, Region, and service that were used to calculate the signature.
This string has the following form:
<AccessKeyId>/<Date>/<Region>/<Service>/wos_request
Where:
<AccessKeyId>: The secret key.
<Date>: In the format of YYYYMMDD.
<Region>: Region name, for example: cn-south-1.
<Service>: Service type, which is fixed at ‘wos’.
SignedHeaders A semicolon-separated list of request headers that you used to compute Signature. The list includes header names only, and the header names must be in lowercase. For example:
host;range;x-wos-date
Signature The 256-bit signature expressed as 64 lowercase hexadecimal characters. For example:
0243fe336dc075f95add64c5fe980ae6fd0446b243e0f301e4ad75d32d96dc6a

Signing steps

1. Create a canonical request

Arrange the contents of your request (host, action, headers, etc.) into a standard (canonical) format. The canonical request is one of the inputs used to create a string to sign.

2. Create a string to sign

Create a string to sign with the canonical request and extra information such as the algorithm, request date, credential scope, and the digest (hash) of the canonical request.

3. Calculate the Signature

In this step, firstly you have to derive a signing key by performing a succession of keyed hash operations (HMAC operations) on the request date, Region, and service, with your secret access key as the key for the initial hashing operation.

After deriving the signing key, you then calculate the signature by performing a keyed hash operation on the string to sign. Use the derived signing key as the hash key for this operation.

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 OS receives the request, it can calculate the same signature that you calculated.

For signatures to match, you must create a canonical request in this format:

<HTTPMethod> + "\n" +
<CanonicalURI> + "\n" +
<CanonicalQueryString> + "\n" +
<CanonicalHeaders> + "\n" +
<SignedHeaders> + "\n" +
<HashedPayload>

In the canonical request:

Field Description
HTTPMethod One of the HTTP methods, for example GET, PUT, HEAD, and DELETE, etc.
CanonicalURI The URI-encoded version of the absolute path component of the URI—everything starting with the “/” that follows the domain name and up to the end of the string or to the question mark character (’?’) if you have query string parameters.

For example, the absolute path of http://Bucket.Endpoint/myphoto.jpg is /myphoto.jpg.
CanonicalQueryString Specifies the URI-encoded query string parameters.

1. For example, request url: http://Bucket.Endpoint?prefix=somePrefix&marker=someMarker&max-keys=20, CanonicalQueryString is:
UriEncode("marker") + "=" + UriEncode("someMarker") + "&" + UriEncode("max-keys") + "=" + UriEncode("20") + "&" + UriEncode("prefix") + "=" + UriEncode("somePrefix")

2. When sub-resource is requested, the value of the query parameter is an empty string “”. For example, request sub-resource acl:http://Bucket.Endpoint?acl
The CanonicalQueryString is UriEncode("acl") + "=" + ""

3. If the URI does not include a ‘?’, there is no query string in the request, and you set the canonical query string to an empty string (""). You will still need to include the “\n”.
CanonicalHeaders A list of request headers with their values. Individual header name and value pairs are separated by the newline character ("\n"). Header names must be in lowercase and arranged in alphabetical order.

The CanonicalHeaders list must include:
1. HTTP host header
2. If the Content-Type header is present in the request, you must add it to the CanonicalHeaders list.
3. Any x-wos-* headers that you plan to include in your request must also be added.

An example of the CanonicalHeaders:
host:bucket.endPoint,x-wos-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b785,x-wos-date:20170524T000000Z

Note:
1. x-wos-content-sha256 is the header that must be included in the signature calculation. It is the hash value of the request payload. If there is no payload, you must provide the hash of an empty string.
2. To prevent data tampering, it is recommended to include all request headers in the signature calculation.
SignedHeaders An alphabetically 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:
host;x-wos-content-sha256;x-wos-date
HashedPayload The hexadecimal value of the SHA256 hash of the request payload. If there is no payload in the request, you compute a hash of the empty string, the hash returns the following value:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

For example, when you upload an object by using a PUT request, you provide object data in the body. When you retrieve an object by using a GET request, you compute the empty string hash.

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:

"WOS-HMAC-SHA256" + "\n" +
TimeStamp + "\n" +
<Scope> + "\n" +
Hex(SHA256Hash(<Canonical Request>))

Where:

  1. WOS-HMAC-SHA256 is a fixed value, specifying the hash algorithm that you are using, HMAC-SHA256;
  2. TimeStamp is the current time in ISO8601 format, yyyyMMdd’T’HHmmss’Z’. This value must match the value you used in any previous steps, such as x-wos-date.
  3. Scope binds the resulting signature to a specific date and a service region. Thus, your resulting signature will work only in the specific Region and is valid for several days after the specified date.
    For example: 20170606/cn-east-1/wos/wos_request
    20170606 indicates that the signature is valid after 20170606. cn-east-1 is the RegionName in OS.
  4. Hex(SHA256Hash(<Canonical Request>)) is the hash of CanonicalRequest that you created in Task 1: Create a canonical request for Signature. This value is not followed by a newline character.

Task 3: Calculate Signature

Before calculating a signature, you have to derive a signing key from your secret access key. Since the signing key is scoped to the date, service, and Region, it offers a greater degree of protection. And then use the signing key and the string to sign that you created in Task 2: Create a string to sign for Signature as the inputs to calculate the signature.

1. Derive your signing key

For signing key, there are steps of calculations, where result of each step you feed into the next step. The final step is the signing key:

1. DateKey = HMAC-SHA256("WOS"+"<SecretKey>", "<Date>")
2. DateRegionKey = HMAC-SHA256(<DateKey>, "<Region>")
3. DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "wos")
4. SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "wos_request")

HMAC-SHA256(key, data) represents an HMAC-SHA256 function that returns output in binary format. <SecretKey> is your secret access key. <Region> is Region Name of your bucket.

Example inputs

SingingKey = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("WOS" + "EfxET06Dvb2cahG8OBtZH9WRqkB3EXAMPLEKEY","20201103"),"cn-south-1"),"wos"),"wos_request")

The example indicates that you are sending a request to OS in the cn-south-1 Region on November 03, 2020).

2. Calculate the signature

The final signature is the HMAC-SHA256 hash of the string to sign, using the signing key as the key. 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.