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 implements
symmetric encryption with an AccessKey pair to verify the identity of the request
sender.
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 Elastic Compute Service (ECS)
console. The AccessKey ID is used to verify identities of users, and the AccessKey
secret is used to encrypt and verify signature strings. You must keep your AccessKey
secret strictly confidential. For more information, see Create an AccessKey pair.
- ECS provides SDKs in multiple programming languages, including third-party SDKs, to
facilitate complex signature calculation. Download the SDK package.
Step 1: Create a canonicalized query string
- Create a canonicalized query string by arranging the request parameters (including
all common and operation-specific parameters except
Signature
) in alphabetical order.
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 (&
).
- Encode the canonicalized query string in UTF-8. Use UTF-8 to encode the names and
values of the request parameters based on RFC 3986.
Encoding rules:
- Uppercase letters, lowercase letters, digits, and some special characters such as
hyphens (-), underscores (_), periods (.), and tildes (~)
do not need to be encoded.
- Other characters must be percent encoded in
%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
%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;
}
- Connect the encoded parameter names and values with equal signs (
=
).
- Connect the encoded request parameters with ampersands (
&
).
Now, you have obtained a canonicalized query string (CanonicalizedQueryString) that
follows the request syntax. For more information, see Call VPC APIs.
Step 2: Create a string-to-sign from the encoded canonicalized query string
- Create
StringToSign
. You can also use
percentEncode
to encode the canonicalized query string created in the previous step. Take the following
steps to create a string-to-sign:
StringToSign=
HTTPMethod + "&" + // HTTPMethod: HTTP method used to make the request, such as GET.
percentEncode("/") + "&" + // percentEncode("/"): Encode the forward slash (/) in UTF-8 as %2F.
percentEncode(CanonicalizedQueryString) //Encode the canonicalized query string created in Step 1.
- Calculate the hash-based message authentication code (HMAC) value of the
StringToSign
, as defined in RFC 2104. Use the Secure Hash Algorithm 1 (SHA-1) algorithm to calculate
the HMAC value. Encode the HMAC value in Base64 to obtain the signature string as
shown below.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
with an ampersand (
&
) which has an ASCII value of 38.
For more information, see Create an AccessKey pair.
- 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:
- Compose and encode a string-to-sign.
http://vpc.aliyuncs.com/?Timestamp=2016-02-23T12%3A46%3A24Z&Format=XML&AccessKeyId=testid&Action=DescribeRegions&SignatureMethod=HMAC-SHA1&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2016-04-28&SignatureVersion=1.0
- 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%3D2016-02-23T12%253A46%253A24Z%26Version%3D2016-04-28
- Calculate the signature. If
AccessKeySecret
is set to testsecret, the key value used for calculation is testsecret&
. The calculated signature is OLeaidS1JvxuMvnyHOwuJ+uX5qY=
. This example uses the Java Base64 encoding method.Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )
- Add the
Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D
string that has been encoded based on RFC 3986 to the URL.http://vpc.aliyuncs.com/?SignatureVersion=1.0&Action=DescribeRegions&Format=XML&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2016-04-28&AccessKeyId=testid&Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D&SignatureMethod=HMAC-SHA1&Timestamp=2016-02-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:
- Predefine an 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;
}
- Predefine the time format for the
Timestamp
parameter. The Timestamp
parameter must conform to the ISO8601 specification and 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);
}
- Create a query string.
final String HTTP_METHOD = "GET";
Map parameters = new HashMap();
//Specify request parameters.
parameters.put("Action", "DescribeRegions");
parameters.put("Version", "2016-04-28");
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");
// Arrange 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 the value.
canonicalizedQueryString.append("&")
.append(percentEncode(key)).append("=")
.append(percentEncode(parameters.get(key)));
}
// Encode the canonicalized query string.
stringToSign.append(percentEncode(
canonicalizedQueryString.toString().substring(1)));
- 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 new URL is:
http://vpc.aliyuncs.com/?SignatureVersion=1.0&Action=DescribeRegions&Format=XML&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2016-04-28&AccessKeyId=testid&Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D&SignatureMethod=HMAC-SHA1&Timestamp=2016-02-23T12%253A46%253A24Z
- Send HTTP requests by using a browser, cURL, or wget.
<DescribeRegionsResponse>
<Regions>
<Region>
<LocalName>China (Qingdao)</LocalName>
<RegionId>cn-qingdao</RegionId>
</Region>
<Region>
<LocalName>China (Hangzhou)</LocalName>
<RegionId>cn-hangzhou</RegionId>
</Region>
</Regions>
<RequestId>833C6B2C-E309-45D4-A5C3-03A7A7A48ACF</RequestId>
</DescribeRegionsResponse>
The returned result 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. For more information, see Error codes.