All Products
Search
Document Center

API Gateway:Backend signature plug-ins

Last Updated:Sep 08, 2023

A backend signature (formerly known as a signature key) is a key-secret pair that you create and issue to API Gateway. This key-secret pair works in a way similar to an account-password pair. After a backend signature plug-in is bound to an API, API Gateway uses the key-secret pair to sign requests designated for your backend service. Your backend service also performs symmetric encryption on the received requests. API Gateway passes authentication if the signature on API Gateway is consistent with that on the backend service.

1. Overview

A backend signature (formerly known as a signature key) is a key-secret pair that you create and issue to API Gateway. API Gateway uses the key-secret pair to sign requests designated for your backend service. Your backend service also performs symmetric encryption on the received requests. API Gateway passes authentication if the signature on API Gateway is consistent with that on the backend service. If your backend service is accessed over a virtual private cloud (VPC), you do not need to use backend signatures because the transmission channel is secure.

The original signature key feature has been integrated into the plug-in system. The original signature key interface and the corresponding console UI are still in use. The original signature key feature and the backend signature plug-in are of the same plug-in type and are subject to the binding limits of that type.

When you create or modify keys in the original signature key interface or console, the data modifications are synchronized to the plug-in system. However, the modifications you make in the plug-in system cannot be synchronized to the original signature key interface or console.

2. Plug-in binding

After you bind a key-secret pair to an API, API Gateway adds the pair to all corresponding requests that are sent to your backend service. The backend service performs symmetric calculation to parse the signature information and authenticate API Gateway.

If you want to replace the pair, you can modify the key and secret in the backend signature plug-in that is bound to the API. The modification takes effect immediately.

3. Plug-in configurations

You can configure your plug-in in JSON or YAML format. The two formats have the same schema. You can use a conversion tool to convert the configuration format. The following code is the configuration template for YAML.

---
type: APIGW_BACKEND
key: SampleKey
secret: SampleSecret
                        

4. Signature reading

The signature is saved in the X-Ca-Proxy-Signature header of a request.

5. Backend signature calculation

For the demo in JAVA for signature calculation, visit https://github.com/aliyun/api-gateway-demo-sign-backend-java.

The following items describe the full process of signature calculation:

  1. API Gateway extracts data from the HTTP request sent to the backend service and combines the data into a signature string. The following example shows the format of the generated signature string:

    HTTPMethod
    Content-MD5
    Headers
    PathAndParameters

    In the preceding example, the four fields constitute an entire signature string and are separated with \n. If the Headers field is left empty, \n is not required. If the other fields are left empty, \n must be retained. The signature is case-sensitive. Data extraction for each field follows the following rules:

    • HTTPMethod: the HTTP method that is used to send a request, such as POST. The value of this field is in uppercase.

    • Content-MD5: the Content-MD5 value that is obtained from the corresponding header in the request sent by the client. If the client does not pass the Content-MD5 header, the Content-MD5 value is left empty in the signature string. The client calculates and transmits the Content-MD5 header only when the request has a body and the body is not a form. The following code shows how the Content-MD5 value is calculated in JAVA:

    String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getbytes("UTF-8")));

    • Headers: the keys and values of all headers involved in signature calculation. Keys are read from request headers and in the X-Ca-Proxy-Signature-Headers format. Multiple keys are separated with commas (,). The keys involved in signature calculation are sorted in alphabetical order, converted into lowercase letters, and then concatenated based on the following rules:

    String headers = HeaderKey1.toLowerCase() + ":" + HeaderValue1 +"\n"+
     HeaderKey2.toLowerCase() + ":" + HeaderValue2 +"\n"+
     ... +
    HeaderKeyN.toLowerCase() + ":" + HeaderValueN + "\n"

    • PathAndParameters

    This field contains all the parameters in the Path, Query, and Form sections. If Query or Form parameters exist, a question mark (?) is added. The keys of the Query and Form parameters are then sorted in alphabetical order and concatenated based on the following rules. If no Query or Form parameters exist, PathAndParameters is set to Path.

    String PathAndParameters =
     Path +
     "?" +
     Key1 + "=" + Value1 
    + "&" + Key2 + "=" + Value2 +
     ... 
    "&" + KeyN + "=" + ValueN

    Note: A Query or Form parameter may have multiple values. If so, only the first value is used for signature calculation. As long as a parameter is passed, the equal sign (=) must be retained during calculation regardless of the situation. For example, if the format of two Query parameters is "path?a=&b", they must be written as "path?a=&b=" in the signature.

  2. The signature is then calculated. The following code snippet provides an example.

Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] keyBytes = secret.getBytes("UTF-8");  //The secret value is the secret in the signature key bound to the API.
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacSHA256"));
String sign = new String(Base64.encodeBase64(Sha256.doFinal(stringToSign.getBytes("UTF-8")),"UTF-8"));

First, a Byte array is obtained after StringToSign is UTF-8-decoded. The Byte array is then encrypted and Base64-encoded to generate the final signature.

6. Debug mode

To access and debug a backend signature efficiently, you can enable the Debug mode. The debugging procedure is to add X-Ca-Request-Mode = debug as a header of the request that is sent to API Gateway.

The backend service can then read the X-Ca-Proxy-Signature-String-To-Sign header in the HTTP header. Line breaks are replaced with number signs (#) in HTTP headers because HTTP headers do not allow line breaks.

Note: X-Ca-Proxy-Signature-String-To-Sign is not involved in backend signature calculation.

7. Timestamp verification

If your backend service needs to verify the timestamp of a request, you can set CaRequestHandleTime to the Greenwich Mean Time (GMT) when API Gateway receives the request in the API definition.