You must sign all HTTP or HTTPS API requests to ensure security. Alibaba Cloud uses the request signature to verify the identity of a request sender. Alibaba Cloud Domains implements symmetric encryption with an AccessKey pair to verify the identity of a request sender. An AccessKey pair consists of an AccessKey ID and an AccessKey secret.

The AccessKey is equivalent to a logon password. However, an AccessKey is used to call APIs, while the logon password is used to log on to the ECS console. Where an AccessKeyID is the visitor identity, an AccessKeySecret is the secret key to encrypt the signature string and to verify the signature string sent to our server. You must keep your AccessKey confidential to prevent possible data breach event.

Note We provide SDKs and third-party SDKs for multiple programming languages to help you skip the authentication process. For more information, see SDK.

Step 1: Create a canonicalized query string

  1. Arrange the request parameters (including Common request parameters and operation-specific parameters except Signature) in alphabetical order.
    Note For example, if you make a request by using the GET method, these parameters are in the section of the URL followed by a question mark ? and connected by ampersands &.
  2. Encode the request parameters by using the UTF-8 character set and according to the RFC3986 rules.
    • Do not encode the A~Z and a~z characters, numbers (0~9), hyphens -, underscores _, periods ., and tildes ~ .

    • Encode other characters in the %XY format, with XY representing the hexadecimal ASCII value of the characters. For example, the half-width double quotes (") are encoded as %22.

    • Encode the extended UTF-8 characters in %XY%ZA… format.

    • Encode the whitespaces ( ) to %20 instead of the plus signs (+).

      Alternatively, you can use libraries that support the application/x-www-form-urlencoded MIME-type URL encoding,

      for example the java.net.URLEncoder of Java language. If so, use the percentEncode Java method, in the encoded strings, replace the plus signs (+) with %20, the asterisks (*) with %2A, and %7E to the tildes (~). See the following example:

      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. Connect the encoded parameters and their values with the equal signs (=).
  4. Use an ampersand (&) to connect the encoded request parameters. These parameters must be sorted in the same order as those in Step 1.

Then, you obtain a canonicalized query string (CanonicalizedQueryString) that follows the request structure. For more information, see Request structure.

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

  1. Create a variable StringToSign by using the canonicalized query string. You can use the aforementioned percentEncode to handle the standardization request string that was constructed by the previous steps, with the following rules:
    StringToSign=
      HTTPMethod + "&" + //HTTPMethod: HTTP method used for making request, for example GET.
      percentEncode("/") + "&" + //percentEncode("/"): Encode backslash (/) to %2F.
      percentEncode(CanonicalizedQueryString) //Encode the canonicalized query string created in the Step 1.
  2. Create a variable Signature by calculating the HMAC-SHA1 value of the StringToSign according to the RFC2104 rules. Here we use the Java Base64 encoding method.
    Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )
    Note RFC2104 when calculating signatures AccessKeySecret followed by the ampersand (&), and the hexadecimal ASCII value of an ampersand is 38.
  3. Encode the value of Signature according to the RFC3986 rules to the canonicalized query string URL.

Example 1: Concatenate parameters

Take calling DescribeRegions as an example. You have the AccessKeyID=testid and AccessKeySecret=testsecret created in the console.

  1. Create a canonicalized query string.
    http://ecs.aliyuncs.com/?Timestamp=2016-02-23T12%3A46%3A24Z&Format=XML&AccessKeyId=testid&Action=DescribeRegions&SignatureMethod=HMAC-SHA1&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2014-05-26&SignatureVersion=1.0
  2. Create StringToSign.
    GET&%2F&AccessKeyId%3Dtestid%26Action%3DDescribeRegions%26Format%3DXML%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3D3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf%26SignatureVersion%3D1.0%26Timestamp%3D2016-02-23T12%253A46%253A24Z%26Version%3D2014-05-26
  3. Calculate the HMAC-SHA1 value. Because you have the AccessKeySecret=testsecret, the Key used in the RFC2104 rules is testsecret&, and the HMAC-SHA1 value is OLeaidS1JvxuMvnyHOwuJ+uX5qY=. Here we use the Java Base64 encoding method.
    Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )
  4. Add the Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D string that has been encoded by using RFC 3986 to the URL in Step 1.
    http://ecs.aliyuncs.com/?SignatureVersion=1.0&Action=DescribeRegions&Format=XML&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2014-05-26&AccessKeyId=testid&Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D&SignatureMethod=HMAC-SHA1&Timestamp=2016-02-23T12%253A46%253A24Z

Sample 2. Programming Language Method

Assume that you are calling the DescribeRegions to describe the Alibaba Cloud region list. You have the AccessKeyID=testid and AccessKeySecret=testsecret created in the console, and all request parameters are stored in a Java Map<String, String> object.

  1. Predefined encoding methods.
    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 format of the parameter Timestamp. The parameter Timestamp must conform to the ISO8601, and use the offset from Coordinated Universal Time (UTC) for the date time.
    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. Construct a request string.
    final String HTTP_METHOD = "GET";
    Map parameters = new HashMap();
    // Add request parameters
    parameters.put("Action", "DescribeRegions");
    parameters.put("Version", "2014-05-26");
    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 parameters
    String[] sortedKeys = parameters.keySet().toArray(new String[]{});
    Arrays.sort(sortedKeys);
    final String SEPARATOR = "&";
    // Create the variable stringToSign
    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 its value
      canonicalizedQueryString.append("&")
      .append(percentEncode(key)).append("=")
      .append(percentEncode(parameters.get(key)));
    }
    // Encode the variable canonicalizedQueryString
    stringToSign.append(percentEncode(
      canonicalizedQueryString.toString().substring(1)));
  4. Sign and encode the signature. Because you have the AccessKeySecret=testsecret, the Key for computing HMAC is testsecret& and the value of signature after calculation is OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D.
    // A sample code for calculating 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));

    After adding the Signature parameter, the request URL encoded according to RFC3986 rules is ready to use.

    http://ecs.aliyuncs.com/?SignatureVersion=1.0&Action=DescribeRegions&Format=XML&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2014-05-26&AccessKeyId=testid&Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D&SignatureMethod=HMAC-SHA1&Timestamp=2016-02-23T12%253A46%253A24Z
  5. Use a Web browser, curl, wget or other tools to send HTTP Request.
    <DescribeRegionsResponse>
     <Regions>
         <Region>
             <LocalName>Qingdao</LocalName>
             <RegionId>cn-qingdao</RegionId>
         </Region>
         <Region>
             <LocalName>Hangzhou</LocalName>
             <RegionId>cn-hangzhou</RegionId>
         </Region>
     </Regions>
     <RequestId>833C6B2C-E309-45D4-A5C3-03A7A7A48ACF</RequestId>
    </DescribeRegionsResponse>

By parsing this XML schema output, you can obtain the region and region ID list of Alibaba Cloud. If you set the Format=JSON, the response results are in JSON format. For more information, see response results.