All Products
Search
Document Center

Signature

Last Updated: Jul 11, 2019

[TOC]

Overview

Each time you send an HTTP or HTTPS request, ApsaraVideo for VOD verifies your identity based on the signature information contained in the request. That is, ApsaraVideo for VOD uses the AccessKey ID and AccessKey Secret for symmetric encryption to verify the identities of request senders.

You can obtain the AccessKey ID and AccessKey Secret from AccessKey management in the Alibaba Cloud console. The AccessKey ID indicates your identity. The AccessKey Secret is used to encrypt the signature string and verify the signature string on the server. You must keep your AccessKey information strictly confidential.

Note: ApsaraVideo for VOD provides SDKs in multiple programming languages and third-party SDKs to free you from complex signature calculation. For more information, download an SDK.

Step 1. Construct a canonicalized query string.

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

    Note: If you use the GET method to send a request, these parameters are contained in the request URL. That is, the string following the question mark (? ) and connected by the ampersand (&) in the URL.

  2. Encode request parameters and their values by using the UTF-8 character set based on the RFC3986 encoding rules as follows:

    • Do not encode uppercase letters A~Z, lowercase letters a~z, digits 0~9, and characters including the hyphen (-), underscore (_), period (.), and tilde (~).

    • Encode other characters in %XY format, where XY indicates the hexadecimal ASCII code of each character. For example, a single-byte double quotation mark (") is encoded as %22.

    • Encode UTF-8 encoded non-ASCII characters into the %XY%ZA… format.

    • Encode a space ( ) as %20 but not the plus sign (+).

    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 of the Java standard library, use percentEncode to encode request parameters and their values. In the encoded characters, 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.

  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 they must be sorted in the same order as that in step 1.

Step 2. Construct a signature string.

  1. Construct the StringToSign string.

    You can also use percentEncode to encode the canonicalized query string constructed in the previous step. The rules are as follows:

    ```

StringToSign= HTTPMethod + "&" + // HTTPMethod: The HTTP method used to send a request, such as GET. percentEncode("/") + "&" + // percentEncode("/"): The UTF-8 encoded value of the forward slash (/), that is, %2F. percentEncode(CanonicalizedQueryString) // Your canonicalized query string.

2. Calculate the HMAC value.

    Based on the definitions in [RFC2104](https://www.ietf.org/rfc/rfc2104.txt?spm=5176.doc54229.2.7.2jcEcp&file=rfc2104.txt "RFC2104"), use the string obtained in the previous step to calculate the HMAC value of the signature.
    > Note: The key used for signature calculation is your `AccessKey Secret` followed by an ampersand (`&`) (ASCII code 38). The algorithm used to calculate your signature is HMAC-SHA1.

3. Obtain the signature string.

    Based on the [Base64 encoding rules] (https://en.wikipedia.org/wiki/Base64 "Base64"), encode the HMAC value obtained in the previous step to obtain the signature string (`Signature`).

4. Add the signature.

    Add the signature value to the request parameters as the `Signature` parameter to complete the request signing process.

    > Note: Before submitting the Signature parameter with the obtained signature string as its value to the server as a request parameter, perform URL encoding for the Signature parameter name and value based on the [RFC3986](http://tools.ietf.org/html/rfc3986?spm=5176.doc54229.2.9.2jcEcp) encoding rules.

## Sample request

The following example shows how to call the GetVideoPlayAuth operation. Assume that `AccessKeyId` is `testAccessKeyId` and `AccessKeySecret` is `testAccessKeySecret`. The following code shows the request URL before a signature is added.

http://vod.cn-shanghai.aliyuncs.com/?TimeStamp=2017-10-10T12:02:54Z&Format=JSON&AccessKeyId=testAccessKeyId&Action=GetVideoPlayAuth&SignatureMethod=HMAC-SHA1&SignatureNonce=8f8a035d-6496-4268-afd4-67c22837e38d&Version=2017-03-21&SignatureVersion=1.0&VideoId=5aed81b74ba84920be578cdfe004af4b

The following code shows the calculated `StringToSign` string.

GET&%2F&AccessKeyId%3DtestAccessKeyId&Action%3DGetVideoPlayAuth&Format%3DJSON&SignatureMethod%3DHMAC-SHA1&SignatureNonce%3D8f8a035d-6496-4268-afd4-67c22837e38d&SignatureVersion%3D1.0&Timestamp%3D2017-10-10T12%253A02%253A54Z&Version%3D2017-03-21&VideoId%3D5aed81b74ba84920be578cdfe004af4b

Because `AccessKeySecret` is `testAccessKeySecret`, the Key used to calculate the HMAC value is `testAccessKeySecret&`. The following code shows the obtained signature string.

Ibgh7y8Vp47LBuAsf5Xhi1SvDss%3D

Use the obtained signature string as the value of the `Signature` parameter and add the parameter to request parameters in the request URL. The following code shows the final URL.

http://vod.cn-shanghai.aliyuncs.com?AccessKeyId=testAccessKeyId&Action=GetVideoPlayAuth&Format=JSON&SignatureMethod=HMAC-SHA1&SignatureNonce=8f8a035d-6496-4268-afd4-67c22837e38d&SignatureVersion=1.0&Timestamp=2017-10-10T12%3A02%3A54Z&Version=2017-03-21&VideoId=5aed81b74ba84920be578cdfe004af4b&Signature=Ibgh7y8Vp47LBuAsf5Xhi1SvDss%3D

## Java sample code

The following sample code shows API common request parameters that you need to generate their values. You can specify other parameters by referring to Common parameters. The following sample code does not depend on any third-party library or package and can be directly used.

### 1. Generate a signature string for the Signature parameter.<div id='Signature'></div>

The procedure for constructing a signature string is as follows:

#### 1.1. Create a canonical request string.
Sort request parameters by their names in ascending order and perform URL encoding.
``` java
/*Perform URL encoding for all parameters and values.*/
public static List<String> getAllParams(Map<String, String> publicParams, Map<String, String> privateParams) {
    List<String> encodeParams = new ArrayList<String>();
    if (publicParams ! = null) {
        for (String key : publicParams.keySet()) {
            String value = publicParams.get(key);
            // Perform URL encoding for the parameter names and values.
            String encodeKey = percentEncode(key);
            String encodeVal = percentEncode(value);
            encodeParams.add(encodeKey + "=" + encodeVal);
        }
    }
    if (privateParams ! = null) {
        for (String key : privateParams.keySet()) {
            String value = privateParams.get(key);
            // Perform URL encoding for the parameter names and values.
            String encodeKey = percentEncode(key);
            String encodeVal = percentEncode(value);
            encodeParams.add(encodeKey + "=" + encodeVal);
        }
    }
    return encodeParams;
}
/*Obtain CanonicalizedQueryString.*/
public static String getCQS(List<String> allParams) {
    ParamsComparator paramsComparator = new ParamsComparator();
    Collections.sort(allParams, paramsComparator);
    String cqString = "";
    for (int i = 0; i < allParams.size(); i++) { 
        cqString += allParams.get(i);
        if (i ! = allParams.size() - 1) {
            cqString += "&";
        }
    }
    return cqString;
}
/*Use a parameter comparator to sort parameters in ascending order.*/
public static class ParamsComparator implements Comparator<String> {
    @Override
    public int compare(String lhs, String rhs) {
        return lhs.compareTo(rhs);
    }
}

1.2. Construct the StringToSign string.

/*Create the StringToSign string.*/
String StringToSign = httpMethod + "&" + percentEncode("/") + "&" + percentEncode(CanonicalizedQueryString); 
/*Replace special characters with escape characters.*/
public static String percentEncode(String value) {
  try {
    String urlEncodeOrignStr = URLEncoder.encode(value, "UTF-8");
    String plusReplaced = urlEncodeOrignStr.replace("+", "%20");
    String starReplaced = plusReplaced.replace("*", "%2A");
    String waveReplaced = starReplaced.replace("%7E", "~");
    return waveReplaced;
  } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
  }
  return value;
}

1.3. Calculate the HMAC value of the StringToSign string.

public static byte[] hmacSHA1Signature(String accessKeySecret, String stringToSign) {
    try {
        String key = accessKeySecret + "&"; 
        try {
              SecretKeySpec signKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
              Mac mac = Mac.getInstance("HmacSHA1");
              mac.init(signKey);
              return mac.doFinal(stringToSign.getBytes());
        } catch (Exception e) {
              throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
        }
    } catch (SignatureException e) {
        e.printStackTrace();
    }
    return null;
}

1.4 Encode the string to obtain the final signature value.

Based on the Base64 encoding rule, encode the HMAC value calculated in 1.3 into a string to obtain the final signature value (Signature).

public static String newStringByBase64(byte[] bytes)
         throws UnsupportedEncodingException {
    if (bytes == null || bytes.length == 0) {
        return null;
    }
    return new String(new BASE64Encoder().encode(bytes));
}

2. Generate a timestamp.

Generate a timestamp in UTC, for example, 2017-10-10T12:02:54Z.

/*Generate a timestamp in UTC.*/
public static String generateTimestamp() {
    Date date = new Date(System.currentTimeMillis());
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    df.setTimeZone(new SimpleTimeZone(0, "GMT"));
    return df.format(date);
}

3. Generate a random number for the SignatureNonce parameter.

public static String generateRandom() {
    String signatureNonce = UUID.randomUUID().toString();
    return signatureNonce;
}

The preceding section has described the sample code used to generate API core parameters. To quickly use the signature, you can download the complete Java sample code for calling APIs from API call examples.

More information

Server SDK

You can directly use a server SDK so that you do not need to calculate the signature. For more information about how to install SDKs in various languages, see the following topics:

The server SDKs package ApsaraVideo for VOD APIs and provide the sample code for each API.

Other signature examples

For more information about how to calculate the signature, see the following sample code of Alibaba Cloud SDKs in various languages: