You must sign all API requests to ensure security. Alibaba Cloud uses the request signature to verify the identity of the API caller. Therefore, each API request must contain signature information, regardless of whether the caller uses HTTP or HTTPS to send the request.

Note
  • The AccessKey pair serves as logon credentials that are used to call API operations, and the username and password are used to log on to the ROS console. The AccessKey ID is used to verify the identity of the user, and the AccessKey secret is used to encrypt and verify the signature string. You must keep your AccessKey secret strictly confidential. For more information, see Create an AccessKey.
  • ROS provides SDKs in multiple programming languages, including third-party SDKs, to facilitate complex signature calculation. For more information, download SDKs.

Step 1: Create a canonicalized query string

  1. Arrange the request parameters (including all common and operation-specific parameters except Signature) in alphabetical order. For more information about common request parameters, see Common parameters.
    Note If you use the GET method to send a request, the request parameters are included as a part of the request URL. The first parameter follows the question mark (?) in the URL, and the other parameters follow an ampersand (&).
  2. Encode the canonicalized query string in UTF-8 based on RFC 3986. The following rules apply in the encoding process:
    • Uppercase letters, lowercase letters, digits, hyphens (-), underscores (_), periods (.), and tildes (~) do not need to be encoded.
    • Other characters must be percent encoded in the %XY format. XY represents the ASCII code of the characters in hexadecimal notation. For example, double quotation marks (") are encoded as %22.
    • Extended UTF-8 characters are encoded in the %XY%ZA... format.
    • Spaces must be encoded as %20. Do not encode spaces as plus signs (+).

      The preceding encoding method is similar to but slightly different from the application/x-www-form-urlencoded MIME-type encoding algorithm.

      If you use java.net.URLEncoder in the Java standard library, use percentEncode to encode request parameters and their values. In the encoded query string, replace the plus sign (+) with %20, the asterisk (*) with %2A, and %7E with a tilde (~). In this way, you can obtain an encoded string that matches the preceding encoding rules.

      private static final String ENCODING = "UTF-8";
      private static String percentEncode(String value) throws UnsupportedEncodingException {
      return value ! = null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
      }
  3. Use an equal sign (=) to connect each encoded request parameter and its value.
  4. Use an ampersand (&) to connect the encoded request parameters. Note that these parameters must be arranged in the same order as those in Step 1.

Now, you have obtained a canoncalized query string (CanonicalizedQueryString) that follows the Request syntax.

Step 2: Create a string-to-sign from the encoded canonicalized query string

  1. Specify StringToSign. You can also use percentEncode to encode the canonicalized query string constructed in the previous step. The following example shows how to create a string-to-sign:
    StringToSign=
      HTTPMethod + "&" + //HTTPMethod: HTTP method used to make the request, such as GET.
      percentEncode("/") + "&" + //percentEncode("/"): Encode backslash (/) as %2F.
      percentEncode(CanonicalizedQueryString) // Encode the canonicalized query string created in Step 1.
  2. Calculate the hash-based message authentication code (HMAC) value of the string-to-sign, as defined in RFC 2104. Use the Secure Hash Algorithm 1 (SHA-1) algorithm to calculate the HMAC value. The HMAC value is encoded in Base64 to obtain the signature string in the following example:
    Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )
    Note When you calculate the signature, the key value specified by RFC 2104 is your AccessKeySecret value with an ampersand (&) which has an ASCII value of 38. For more information, see Create an AccessKey.
  3. Encode the Signature parameter based on RFC 3986 and add it to the canonicalized query string.

Example 1: Concatenate parameters

The DescribeRegions operation is called to query Alibaba Cloud regions in the following example. This example shows the signature process when AccessKeyID is set to testid and AccessKeySecret is set to testsecret:

  1. Create a canonicalized query string.
    http://ros.aliyuncs.com/?Timestamp=2019-08-23T12%3A46%3A24Z&Format=XML&AccessKeyId=testid&Action=DescribeRegions&SignatureMethod=HMAC-SHA1&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2019-09-10&SignatureVersion=1.0
  2. Create a string-to-sign.
    GET&%2F&AccessKeyId%3Dtestid%26Action%3DDescribeRegions%26Format%3DXML%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3D3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf%26SignatureVersion%3D1.0%26Timestamp%3D2019-08-23T12%253A46%253A24Z%26Version%3D2019-09-10
  3. Calculate the signature. If AccessKeySecret is set to testsecret, the key value used for calculation is testsecret&. The calculated signature is OLeaidS1JvxuMvnyHOwuJ+uX5qY=. The Java Base64 encoding method is used in the following example:
    Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )
  4. Add the Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D string that has been encoded based on RFC 3986 to the URL in Step 1.
    http://ros.aliyuncs.com/?SignatureVersion=1.0&Action=DescribeRegions&Format=XML&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2019-09-10&AccessKeyId=testid&Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D&SignatureMethod=HMAC-SHA1&Timestamp=2019-08-23T12%253A46%253A24Z

You can use browsers or tools such as cURL and Wget to initiate an HTTP request through the new URL. The HTTP request calls the DescribeRegions operation to query the Alibaba Cloud region list.

Example 2: Use the standard library of the programming language

The DescribeRegions operation is called to query Alibaba Cloud regions in the following example. This example shows the signature process when AccessKeyID is set to testid and AccessKeySecret is set to testsecret, and all request parameters are placed in a Java Map<String, String> object:

  1. Predefine the encoding method.
    private static final String ENCODING = "UTF-8";
    private static String percentEncode(String value) throws UnsupportedEncodingException {
      return value ! = null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
    }
  2. Predefine the time format for the Timestamp parameter. The Timestamp value must be specified in the ISO 8601 standard. The time must be in UTC+0.
    private static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    private static String formatIso8601Date(Date date) {
      SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
      df.setTimeZone(new SimpleTimeZone(0, "GMT"));
      return df.format(date);
    }
  3. Create a query string.
    final String HTTP_METHOD = "GET";
    Map parameters = new HashMap();
    // Specify request parameters.
    parameters.put("Action", "DescribeRegions");
    parameters.put("Version", "2019-09-10");
    parameters.put("AccessKeyId", "testid");
    parameters.put("Timestamp", formatIso8601Date(new Date()));
    parameters.put("SignatureMethod", "HMAC-SHA1");
    parameters.put("SignatureVersion", "1.0");
    parameters.put("SignatureNonce", UUID.randomUUID().toString());
    parameters.put("Format", "XML");
    //Sort the request parameters.
    String[] sortedKeys = parameters.keySet().toArray(new String[]{});
    Arrays.sort(sortedKeys);
    final String SEPARATOR = "&";
    // Create a string-to-sign.
    StringBuilder stringToSign = new StringBuilder();
    stringToSign.append(HTTP_METHOD).append(SEPARATOR);
    stringToSign.append(percentEncode("/")).append(SEPARATOR);
    StringBuilder canonicalizedQueryString = new StringBuilder();
    for(String key : sortedKeys) {
    // Encode the key and value.
      canonicalizedQueryString.append("&")
      .append(percentEncode(key)).append("=")
      .append(percentEncode(parameters.get(key)));
    }
    // Encode the canonicalized query string.
    stringToSign.append(percentEncode(
      canonicalizedQueryString.toString().substring(1)));
  4. Calculate the signature. If AccessKeySecret is set to testsecret, the key used for calculation is testsecret&. The calculated signature is OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D.
    // The following code demonstrates how to calculate the signature:
    final String ALGORITHM = "HmacSHA1";
    final String ENCODING = "UTF-8";
    key = "testsecret&";
    Mac mac = Mac.getInstance(ALGORITHM);
    mac.init(new SecretKeySpec(key.getBytes(ENCODING), ALGORITHM));
    byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING));
    String signature = new String(Base64.encodeBase64(signData));

    Encode the Signature parameter based on RFC 3986 and add the parameter to the URL. The following URL is obtained after encoding:

    http://ros.aliyuncs.com/?SignatureVersion=1.0&Action=DescribeRegions&Format=XML&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2019-09-10&AccessKeyId=testid&Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D&SignatureMethod=HMAC-SHA1&Timestamp=2019-08-23T12%253A46%253A24Z
  5. Use browsers or tools such as cURL and Wget to send HTTP requests.
    <DescribeRegionsResponse>
        <Regions>
            <Region>
                <RegionId>cn-qingdao</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>China (Qingdao)</LocalName>
            </Region>
            <Region>
                <RegionId>cn-beijing</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>China (Beijing)</LocalName>
            </Region>
            <Region>
                <RegionId>cn-zhangjiakou</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>China (Zhangjiakou-Beijing Winter Olympics)</LocalName>
            </Region>
            <Region>
                <RegionId>cn-huhehaote</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>China (Hohhot)</LocalName>
            </Region>
            <Region>
                <RegionId>cn-hangzhou</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>China (Hangzhou)</LocalName>
            </Region>
            <Region>
                <RegionId>cn-shanghai</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>China (Shanghai)</LocalName>
            </Region>
            <Region>
                <RegionId>cn-shenzhen</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>China (Shenzhen)</LocalName>
            </Region>
            <Region>
                <RegionId>cn-chengdu</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>China (Chengdu)</LocalName>
            </Region>
            <Region>
                <RegionId>ap-northeast-1</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>Japan (Tokyo)</LocalName>
            </Region>
            <Region>
                <RegionId>ap-southeast-1</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>Singapore</LocalName>
            </Region>
            <Region>
                <RegionId>ap-southeast-2</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>Australia (Sydney)</LocalName>
            </Region>
            <Region>
                <RegionId>ap-southeast-3</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>Malaysia (Kuala Lumpur)</LocalName>
            </Region>
            <Region>
                <RegionId>ap-southeast-5</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>Indonesia (Jakarta)</LocalName>
            </Region>
            <Region>
                <RegionId>ap-south-1</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>India (Mumbai)</LocalName>
            </Region>
            <Region>
                <RegionId>us-east-1</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>US (Virginia)</LocalName>
            </Region>
            <Region>
                <RegionId>us-west-1</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>US (Silicon Valley)</LocalName>
            </Region>
            <Region>
                <RegionId>eu-west-1</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>UK (London)</LocalName>
            </Region>
            <Region>
                <RegionId>me-east-1</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>UAE (Dubai)</LocalName>
            </Region>
            <Region>
                <RegionId>eu-central-1</RegionId>
                <RegionEndpoint>ros.aliyuncs.com</RegionEndpoint>
                <LocalName>Germany (Frankfurt)</LocalName>
            </Region>
        </Regions>
        <RequestId>59F0F0A0-A637-4292-9B91-251EF5010913</RequestId>
    </DescribeRegionsResponse>

The response lists regions and region IDs. If you set Format to JSON when you submit a request, the response is returned in the JSON format instead of the XML format.