Request Signature V4

Last updated:2021-04-28 11:04:11

When using KS3, you can initiate an anonymous or signed HTTP request to KS3 through the RESTful API. If you initiate a signed HTTP request, the KS3 server will authenticate your identity.

  • Anonymous HTTP request: an HTTP request that does not carry any identity or authentication information, and is initiated through the RESTful API.
  • Signed HTTP request: an HTTP request that carries a signature. After receiving the request, the KS3 server authenticates the request initiator. If the authentication succeeds, the KS3 server accepts and executes the request. Otherwise, the KS3 server returns an error message and discards the request.

KS3 Signature V4 is compatible with AWS Signature Version 4. For more information, see Authenticating Requests (AWS Signature Version 4).


If you use the SDK for development, the API request signing method described in this topic is not required, because the SDK contains the signature calculation method. The following procedure is required only when you want to use the original API for secondary development.

V4 signing process

1. Create a string-to-sign

1.1 Create a canonical request


CanonicalRequest = HTTPRequestMethod + '\n'
		+ CanonicalURI + '\n'
		+ CanonicalQueryString + '\n'
		+ CanonicalHeaders + '\n'
		+ SignedHeaders + '\n'
		+ HexEncode(Sha256Hash(RequestPayload))



The request starts with the HTTP request method, including GET, PUT, POST, and DELETE.



  • The requested resource is URL-encoded, but the slash (/) is not encoded.

  • The question mark (?) and the following query string are not included.

  • For more information about URL encoding, see URL encoding method.

  • BucketName is part of the host header. If BucketName is not specified, the requested resource is represented by a slash (/).

  • In the bucket list query operation, the requested resource is represented by a slash (/).


Add a canonical query string, followed by a newline character.

If the request does not contain a query string, use an empty string, which is actually a blank line.

To construct a canonical query string, perform the following steps:

  • Sort parameter names in ascending order of character code points. Sort parameters with the same name by their values. For example, a parameter name starting with an uppercase letter F precedes that starting with a lowercase letter b.

  • URI-encode all parameter names and values according to the following rules:

  • Construct a standard query string by starting with the first parameter name in the sorted list.

  • For each parameter, add a URI-encoded parameter name, an equals sign (=), and a URI-encoded parameter value in sequence. If a parameter has no value, use an empty string.

  • Add an ampersand (&) to the end of each parameter value, except the last parameter value in the list.

Calculation formula:

UriEncode("query2")+"="+UriEncode("value2") + "&" +


Add canonical request headers. Separate key-value pairs of each request header by “\n”, and connect a key and its value by a colon(":").

Before you construct a request, sort header names in ascending order of characters.

Convert header names into lowercase letters and remove the spaces before and after values.

Construction formula:


CanonicalHeaders contains the following headers:

  • The host header is required.

  • If the request headers include Content-Type, it must be added to CanonicalHeaders.

  • Any request header starting with x-kss- must be added to CanonicalHeaders.

  • The x-kss-security-token header is required for temporary authorization.

  • The x-kss-content-sha256 header is required.

  • In addition to the preceding headers, SignedHeaders is also required in calculation.

  • The Authorization header is not required for calculating the signature.


To prevent the request headers from being tampered with, authentication headers are added for an authentication operation. The authentication headers are the same as those included in CanonicalHeaders, and are separated by semicolons(:). The pseudocode is as follows:


The timestamp (x-kss-date or Date header) is valid within 15 minutes. Unauthorized users can intercept the signed request and modify the content not included in SignedHeaders. Therefore, we recommend that you sign all request headers and request bodies.


The x-kss-content-sha256 header is required. The following table lists its values.

Value Description
HexEncode(Sha256Hash(RequestPayload)) The lowercase hexadecimal string representing the hashed request body.
UNSIGNED-PAYLOAD The hash check ignoring the request body.
STREAMING-AWS4-HMAC-SHA256-PAYLOAD The chunk transmission check based on the new API protocol of AWS Signature Version 4, which is unavailable currently.

Calculation method:

HashedPayload = Lowercase(HexEncode(SHA256Hash(requestPayload)))

Create a hash value based on the payload in the HTTP or HTTPS request body by using SHA256 or other hash (digest) functions. Signature Version 4 does not require that you use specific character encoding to encode the text in the payload.

After you create a string-to-sign, specify the signing algorithm used to hash the payload. For example, if you use SHA256, specify KSS4-HMAC-SHA256 as the signing algorithm. The hashed payload must be represented as a lowercase hexadecimal string.

If the payload is empty, use an empty string as the input of the hash function.

1.2 Create a string-to-sign

To create a string-to-sign, concatenate the algorithm, date and time, credential scope, and digest of the canonical request, as shown in the following pseudocode:

Structure of the string-to-sign:

StringToSign =
    Algorithm + \n +
    RequestDateTime + \n +
    CredentialScope + \n +

To create a string-to-sign, perform the following steps:

  • Start with the algorithm name, followed by a newline character. This value is the hash algorithm you use to calculate the digest of the canonical request. For SHA256, the algorithm name is KSS4-HMAC-SHA256.

  • Append the request date, followed by a newline character. The date is specified in the x-kss-date (x-maz-date) header in the ISO 8601 basic format: YYYYMMDD’T’HHMMSS’Z’. This value must be the same as that you used in all the preceding steps.

  • Append the credential scope, followed by a newline character. This value is a string consisting of the date, target region, requested service, and lowercase termination string (kss4_request). The region name and service name must be UTF-8-encoded.

date.Format(<YYYYMMDD>) + "/" + <region> + "/" + <service> + "/kss4_request"

The date must be in the format of YYYYMMDD. The date does not contain specific time.

Make sure that the specified region is the region to which you want to send the request.
The region ID of China (Beijing) in KS3 is BEIJING. For more information, see Endpoint and Region.

2. Calculate a signing key

Signing key:
To sign your message, you must use your AccessKey to calculate a signing key. To do so, use your AccessKey to create a series of hash-based message authentication codes (HMACs). The HMACs are shown in the following pseudocode, where HMAC(key, data) indicates the HMAC-SHA256 function that returns the output in binary format. The result of each hash function is the input of the next function.

Pseudocode for calculating the signing key:

kSecret = your Access Key 
kDate = HMAC("KSS4" + kSecret, Date)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigning = HMAC(kService, "kss4_request")

The date used in the hashing process is in the format of YYYYMMDD, such as 20150830, excluding specific time.

Specify HMAC parameters in the correct order for the programming language you want to use. In this example, the first parameter is the key, and the second parameter is the data (message), but the function you use may specify the key and data in a different order.

Use the digest (in binary format) to derive the key. Most languages provide functions for calculating binary hash values, usually called digests, or hex-encoded hash values, called hexadecimal digests. The derived key requires a digest in binary format.

The following example shows the input for calculating the signing key and the output generated, where kSecret = wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY.

Sample input:

HMAC(HMAC(HMAC(HMAC("KSS4" + kSecret,"20150830"),"BEIJING"),"ks3"),"kss4_request")

3. Calculate a signature

Calculation formula:

HMAC-SHA256(SigningKey, StringToSign)

Use a signature

The signature of a signed HTTP request initiated to KS3 through the RESTful API can be passed in the following ways:

Add the signature to a standard HTTP Authorization header

The Authorization header is in the following format:

Authorization: algorithm Credential=access key ID/credential scope, SignedHeaders=SignedHeaders, Signature=signature


PUT /test/uploadfile HTTP/1.1
X-Amz-Date: 20190927T100359Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIAIPXSWFJRPW3RWPJ8PK/20190927/us-west-2/s3/aws4_request, SignedHeaders=amz-sdk-invocation-id;amz-sdk-retry;content-length;content-type;host;user-agent;x-amz-content-sha256;x-amz-date, Signature=6d9df5717ebb7cdeae7d08d817b80d6a90ca32320b07e46f30c64136eade9d48
amz-sdk-retry: 0/0/500
User-Agent: aws-sdk-java/1.11.311 Windows_8.1/6.3 Java_HotSpot(TM)_64-Bit_Server_VM/24.60-b09 java/1.7.0_60
x-amz-content-sha256: f68d27da17d9fd49440b0b8dac130f4f98a2d4c6aca3c9221cdbc8b264b2c8be
amz-sdk-invocation-id: e5d51221-298a-2fc0-3adf-09390a1f5beb
Content-Type: text/plain
Content-Length: 6
Connection: Keep-Alive

Add the signature to a URL query string


The signature in the URL query string is calculated in the same way as that in the Authorization header.

The following table describes the parameters in the query string.

Parameter Description
X-Kss-Algorithm The signing algorithm, which is HMAC-SHA256.
X-Kss-Credential The credential scope in the format of <your-access-key-id>/<date>/<KS3-region>/<KS3>/kss4_request.
X-Kss-Date The request time in the format of yyyyMMddTHHmmssZ. X-Kss-Date ≤ now + 15 minutes.
X-Kss-Expires The validity period, in seconds. The value ranges from 1 to 604800 (7 days). X-Kss-Date + X-Kss-Expires ≥ now.
X-Kss-SignedHeaders The signed headers.
X-Kss-Signature The signature. The query string used for calculating a signature does not contain X-Kss-Signature.

Add the signature to a form

For a verified POST request, the HTML form must contain the policy and signature.
The policy specifies which values are allowed in the request.

To calculate a signature, perform the following steps:

  1. Create a UTF-8-encoded policy file. For more information about how to create a policy, see Postpolicy.

  2. Base64-encode the policy. The code value is the value of the policy field in the form, and is used as the string-to-sign.

  3. Calculate the signature as follows: Signature = HMAC-SHA256(SigningKey, StringToSign).

Form field Description
policy The form upload security policy.
X-Kss-Algorithm The signing algorithm, which is HMAC-SHA256.
X-Kss-Credential The credential scope in the format of <your-access-key-id>/<date>/<KS3-region>/<KS3>/kss4_request.
X-Kss-Date The request time in the format of yyyyMMddTHHmmssZ. X-Kss-Date ≤ now + 15 minutes.
X-Kss-Signature The signature. The query string used for calculating a signature does not contain X-Kss-Signature.

Other instructions

1. Date

The date in the credential scope must be the same as the request date. You can add the date to the request in a variety of ways. For example, you can add the Date or x-kss-date (x-amz-date) header or the x-kss-date (x-amz-date) query parameter to the request.

The timestamp must be UTC time in the ISO 8601 format: YYYYMMDD’T’HHMMSS’Z’. For example, 20150830T123600Z is a valid timestamp. The timestamp does not contain milliseconds.

Verify the x-kss-date (x-amz-date) header or parameter of the timestamp. If no value of the x-kss-date (x-amz-date) header is found, verify the Date header. Verify the credential scope in the form of an eight-digit string representing the request year (YYYY), month (MM), and day (DD). For example, if the value of the x-amz-date header is 20111015T080000Z and the date in the credential scope is 20111015, the authentication is allowed to continue.

If the dates are different, the request is denied, even if the difference is within seconds. For example, if the value of the x-kss-date (x-amz-date) header is 20151014T235959Z and the date in the credential scope is 20151015, the request is denied.

2. URL encoding method

  • Do not URI-encode any non-reserved characters defined by RFC 3986, including A–Z, a–z, 0–9, hyphens (-), underscores (_), periods (.), and tildes (~).
  • Encode spaces into %20. Spaces are encoded into plus signs (+) in other encoding solutions.
  • Percent-encode all other characters with %XY. X and Y are hexadecimal characters 0–9 and A–F. You can extend UTF-8 characters in the format of %XY%ZA%BC.
  • Encode forward slashes (/), except those in object names.

3. Protocol headers

The AWS protocol starts with x-amz-. The KS3 protocol starts with x-kss-. The KS3 protocol is compatible with the AWS protocol and supports KS3 Signature V4.

- s3 ks3
Request header prefix x-amz- x-kss-
Query string prefix X-Amz- X-Kss-
Protocol AWS4 KSS4
Product s3 ks3
Fixed value aws4_request kss4_request

Did you find the above information helpful?

Mostly Unhelpful
A little helpful
Very helpful

What might be the problems?

Unclear or awkward
Redundant or clumsy
Lack of context for the complex system or functionality

More suggestions


Please give us your feedback.


Thank you for your feedback.