Signature

Last Updated: Apr 25, 2018

We perform the sender authentication for each request. Therefore, a signature information must be included in the request, irrespective of the use of HTTP or HTTPS protocol. By using the AccessKeyID and AccessKeySecret, we perform symmetric encryption to authenticate the sender request.

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 console. For more information, see Create AccessKey. The AccessKeyID indicates your identity. The 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: In particular, you can skip the authentication process by using the SDK, CLI, and API Explorer. It is easier for you to get started by using the language-specific SDK instead of making a request over HTTP or HTTPS. For more information, see Developer Resources.

Procedure

Step 1. Compose a standardized request URL

  1. Sort the request parameters in an lexicographical order. The request parameters include the API-specific parameters and common request parameters except for the Signature parameter.

    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 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:

      1. private static final String ENCODING = "UTF-8";
      2. private static String percentEncode(String value) throws UnsupportedEncodingException {
      3. return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
      4. }
  3. Connect the encoded parameters and their values with the equal signs (=).

  4. Concatenate the encoded parameters with ampersands (&).

Now, you get a standardized request URL, the structure of the URL must be the same as described in the topic Request structure.

Step 2. Calculate the signature

  1. Create a variable StringToSign by using the standardized request URL. You can use the aforementioned percentEncode Java method.

    1. StringToSign=
    2. HTTPMethod + "&" + //HTTPMethod: HTTP method used for making request, for example GET.
    3. percentEncode("/") + "&" + //percentEncode("/"): Encode backslashe (/) to %2F.
    4. percentEncode(CanonicalizedQueryString) //Encode the standardized request URL created in the Step 1.
  2. Create a variable Signature by calculating the HMAC-SHA1 value of the StringToSign according the RFC2104 rules. Here we use the Java Base64 encoding method.

    1. Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )

    Note: The Key is your AccessKeySecret followed by the ampersand (&), and the hexadecimal ASCII value of an ampersand (&) is 38. For more information, see Create AccessKey.

  3. Encode the value of Signature according to the RFC3986 rules.

  4. Add the encoded Signature to the standardized request URL.

Sample 1

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.

  1. Create a standardized request URL.

    1. http://ecs.aliyuncs.com/?Timestamp=2016-02-23T12:46:24Z&Format=XML&AccessKeyId=testid&Action=DescribeRegions&SignatureMethod=HMAC-SHA1&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2014-05-26&SignatureVersion=1.0
  2. Create a variable StringToSign to be calculated by using the standardized request URL.

    1. GET&%2F&AccessKeyId%3Dtestid&Action%3DDescribeRegions&Format%3DXML&SignatureMethod%3DHMAC-SHA1&SignatureNonce%3D3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&SignatureVersion%3D1.0&Timestamp%3D2016-02-23T12%253A46%253A24Z&Version%3D2014-05-26
  3. Create a variable Signature by calculating the HMAC-SHA1 value of the StringToSign. Because you have the AccessKeySecret=testsecret, the Key used in the RFC2104 rules is testsecret&, and we use the Java Base64 encoding method for calculating.

    1. Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )
  4. Encode the value of Signature according to the RFC3986 rules, and get the result Signature=CT9X0VtwR86fNWSnsc6v8YGOjuE%3D.

  5. Add the Signature=CT9X0VtwR86fNWSnsc6v8YGOjuE%3D to the URL created in the step 1.

    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=CT9X0VtwR86fNWSnsc6v8YGOjuE%3D&SignatureMethod=HMAC-SHA1&Timestamp=2018-04-17T03%3A09%3A55Z

Now you can use a Web browser, curl, or wget tool to send the preceding URL.

Sample 2

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. See the following sample by using the Java programming language.

  1. Predefine the encode method by using the percentEncode method.

    1. private static final String ENCODING = "UTF-8";
    2. private static String percentEncode(String value) throws UnsupportedEncodingException {
    3. return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
    4. }
  2. Predefine the format of the parameter Timestamp according to the ISO8601, and use the offset from Coordinated Universal Time (UTC) for the date and time.

    1. private static final String ISO8601_DATE_FORMAT = "YYYY-MM-DD'T'HH:mm:ss'Z'";
    2. private static String formatIso8601Date(Date date) {
    3. SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
    4. df.setTimeZone(new SimpleTimeZone(0, "GMT"));
    5. return df.format(date);
    6. }
  3. Create the request URL. We place all the request parameters in a Map<String, String> object.

    1. final String HTTP_METHOD = "GET";
    2. Map<String, String> parameters = new HashMap<String, String>();
    3. // Add request parameters
    4. parameters.put("Action", "DescribeRegions");
    5. parameters.put("Version", "2014-05-26");
    6. parameters.put("AccessKeyId", "testid");
    7. parameters.put("Timestamp", formatIso8601Date(new Date()));
    8. parameters.put("SignatureMethod", "HMAC-SHA1");
    9. parameters.put("SignatureVersion", "1.0");
    10. parameters.put("SignatureNonce", UUID.randomUUID().toString());
    11. parameters.put("Format", "XML");
    12. // Sort the parameters
    13. String[] sortedKeys = parameters.keySet().toArray(new String[]{});
    14. Arrays.sort(sortedKeys);
    15. final String SEPARATOR = "&";
    16. // Create the variable stringToSign
    17. StringBuilder stringToSign = new StringBuilder();
    18. stringToSign.append(HTTP_METHOD).append(SEPARATOR);
    19. stringToSign.append(percentEncode("/")).append(SEPARATOR);
    20. StringBuilder canonicalizedQueryString = new StringBuilder();
    21. for(String key : sortedKeys) {
    22. // Encode the key and its value
    23. canonicalizedQueryString.append("&")
    24. .append(percentEncode(key)).append("=")
    25. .append(percentEncode(parameters.get(key)));
    26. }
    27. // Encode the variable canonicalizedQueryString
    28. stringToSign.append(percentEncode(
    29. canonicalizedQueryString.toString().substring(1)));
  4. Sign and encode the signature. Because you have the AccessKeySecret=testsecret, the Key used in the RFC2104 rules is testsecret&.

    1. // A sample code for calculating the signature
    2. final String ALGORITHM = "HmacSHA1";
    3. final String ENCODING = "UTF-8";
    4. key = "testsecret&";
    5. Mac mac = Mac.getInstance(ALGORITHM);
    6. mac.init(new SecretKeySpec(key.getBytes(ENCODING), ALGORITHM));
    7. byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING));
    8. String signature = new String(Base64.encodeBase64(signData));

    The value of signature after calculation is CT9X0VtwR86fNWSnsc6v8YGOjuE%3D. After adding the Signature parameter, the request URL is ready to use.

    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=CT9X0VtwR86fNWSnsc6v8YGOjuE%3D&SignatureMethod=HMAC-SHA1&Timestamp=2018-04-17T03%3A09%3A55Z
  5. Use a Web browser, curl, or wget tool to make an HTTP request.

    1. <DescribeRegionsResponse>
    2. <Regions>
    3. <Region>
    4. <LocalName>Qingdao</LocalName>
    5. <RegionId>cn-qingdao</RegionId>
    6. </Region>
    7. <Region>
    8. <LocalName>Hangzhou</LocalName>
    9. <RegionId>cn-hangzhou</RegionId>
    10. </Region>
    11. </Regions>
    12. <RequestId>833C6B2C-E309-45D4-A5C3-03A7A7A48ACF</RequestId>
    13. </DescribeRegionsResponse>

By parsing this XML schema output, you can obtain the region and region ID list of Alibaba Cloud. If you set the Format to JSON, the response is JSON formatted. For more information, see Response results.

Thank you! We've received your feedback.