Key Management Service (KMS) uses a request signature to verify the identity of an API caller. This ensures data security when you call API operations.

Security verification

Security verification is based on the client key that is bound to the application access point (AAP) of KMS and is used to perform the following operations by using asymmetric signature algorithms:

  • Verifies the identity of the user who sends the API request.

    Before a user sends a request, the user must specify the client key that is bound to the AAP to generate a signature. The identity of the user is identified based on the client key on the server. This way, access permissions can be managed in an efficient manner.

  • Checks whether the API request is tampered with during transmission.

    The server verifies the signature of the received request. If the request is tampered with during transmission, the request cannot pass signature verification.

The following process describes the security verification for an API request:

  1. The client generates a string-to-sign based on the HTTP header and body of the API request.
  2. The client signs the string that is generated in Step 1 by using the private key of the client key that is bound to the AAP to generate a signature for the API request. The PrivateKeyData parameter specifies the private key.
  3. The client sends the API request data and the signature to the server.
  4. After the server receives the request, the server uses the public key of the client key to verify the signature. If the signature passes the verification, the API request is accepted. If the signature fails the verification, the API request is rejected.
    Note The server obtains the public key of the client key that is bound to the AAP in the backend.

Signature process

To ensure that an API request passes the security verification, sign the API request on the client to generate a signature and use the HTTP Authorization header to transmit the signature. The following example shows an HTTP Authorization header:
Authorization = "TOKEN" + " " + Signature

A signature is generated by using the private key of the client key that is bound to the AAP to sign the API request. The following process describes how to generate a signature:

  1. Obtain the client key that is bound to the AAP.
    The private key of the client key is required to generate a signature for the API request. You can use an existing client key or create a client key. Make sure that the client key is in the enabled state.
  2. Generate a string-to-sign for the API request.
    The string-to-sign contains information, such as the HTTP request method, HTTP request headers, and HTTP request body. The string-to-sign is in the following format:
    SignString = HTTP-METHOD + "\n"
                 + CONTENT-SHA256 + "\n"
                 + CONTENT-TYPE + "\n"
                 + DATE + "\n"
                 + CanonicalizedKMSHeaders + "\n"
                 + CanonicalizedResource
    \n is a line feed, and the plus sign (+) is a string concatenation operator. The following table describes other headers.
    HeaderDescriptionExample
    HTTP-METHODThe HTTP request method. PUT, GET, and POST
    CONTENT-SHA256The SHA-256 hash value of the request content. AE71057543002AD513AB88D78509A1214192C09F20302C4BF8F59B7EB565****
    CONTENT-TYPEThe type of the HTTP request body. application/x-protobuf
    DATEThe standard timestamp header of the HTTP request. This header follows the RFC 1123 format. The time is in Coordinated Universal Time (UTC). Mon, 27 Sep 2021 11:47:26 GMT
    CanonicalizedKMSHeadersThe string that consists of the custom headers prefixed with x-kms in the HTTP request. x-kms-acccesskeyid:KAAP.9c84ad54-d3c5-47c3-b0e7-7c26d509****\nx-kms-apiname:Encrypt\nx-kms-apiversion:dkms-gcs-0.2\nx-kms-signaturemethod:RSA_PKCS1_SHA_256
    CanonicalizedResourceThe value is fixed as /. /
    If an HTTP request does not have a body, the CONTENT-SHA256 and CONTENT-TYPE headers are empty strings. The string-to-sign is in the following format:
    SignString = HTTP-METHOD + "\n"
                 + "\n"
                 + "\n"
                 + DATE + "\n"
                 + CanonicalizedKMSHeaders + "\n"
                 + CanonicalizedResource
    KMS API introduces custom headers that are prefixed with x-kms. If you specify a custom header in an API request, the value of this header is used to calculate a signature. The following process describes how to generate the CanonicalizedKMSHeaders header:
    1. Convert all HTTP header names that are prefixed with x-kms to lowercase.
    2. Sort all custom request headers in alphabetical order.
    3. Delete all spaces on each side of the delimiter between each header and the value of the header. For example: CONTENT-TYPE : application/x-protobuf is converted to CONTENT-TYPE:application/x-protobuf.
    4. Separate all headers and the values of the headers with the \n delimiter to obtain the CanonicalizedKMSHeaders header.
  3. Generate a signature for the request.
    KMS API supports only the signature algorithm RSA_PKCS1_SHA_256. You can generate a signature by using the following formula:
    Signature=Base64(RSA_PKCS1_SHA_256(SignString, AAP_KEY))

    When you generate a signature, take note of the following items:

    • You must encode the value that is generated by the signature algorithm in Base64.
    • You must use the RSASSA-PKCS1-v1_5 signature algorithm to sign the string-to-sign. For more information about the RSASSA-PKCS1-v1_5 signature algorithm, visit RFC 3447.
    • After you generate the signature, add the signature to the Authorization header.
    • The string-to-sign must be encoded in UTF-8. If the string-to-sign contains Chinese characters, you must encode the string in UTF-8 before you calculate a signature.
    • The CONTENT-SHA256 and CONTENT-TYPE headers are not required in the request. If the CONTENT-SHA256 and CONTENT-TYPE headers are empty, you must replace the values of the headers with line feeds \n.

Signature example

The following example shows how an API request is signed. In this example, the Encrypt operation is used.

KMS API uses the following client key that is bound to the AAP and the encryption parameters of the Encrypt operation:
  • Client key that is bound to the AAP
    {
      "KeyId": "KAAP.9c84ad54-d3c5-47c3-b0e7-7c26d509****",
      "PrivateKeyData": "MIIJqwIB****UcQ=="
    }
  • Encryption parameters of the Encrypt operation
    keyId = "1234abcd-12ab-34cd-56ef-12345678****"
    plaintext = "plain text"

The following process shows the signature process:

  1. Construct the following HTTP request based on the definition of KMS API.
    POST / HTTP/1.1
    Date: Mon, 27 Sep 2021 11:47:26 GMT
    Host: kst-xxxx.cryptoservice.kms.aliyuncs.com
    Accept: application/x-protobuf
    Content-SHA256: AE71057543002AD513AB88D78509A1214192C09F20302C4BF8F59B7EB565****
    Content-Length: 40
    Content-Type: application/x-protobuf
    x-kms-acccesskeyid: KAAP.9c84ad54-d3c5-47c3-b0e7-7c26d509****
    x-kms-apiversion: dkms-gcs-0.2
    x-kms-apiname: Encrypt
    x-kms-signaturemethod: RSA_PKCS1_SHA_256
    
    <The encryption parameters are serialized into byte streams in the Protocol Buffers format.>

    The byte streams in the Protocol Buffers format are used as the request body. The value of the Content-Type header in the request is set to application/x-protobuf. The value of the Content-SHA256 header is set to the hex string in uppercase that is generated after the request body is calculated by using SHA-256.

  2. Construct a string-to-sign.
    POST\nAE71057543002AD513AB88D78509A1214192C09F20302C4BF8F59B7EB56551E2\napplication/x-protobuf\nMon, 27 Sep 2021 11:47:26 GMT\nx-kms-acccesskeyid:KAAP.9c84ad54-xxxx-xxxx-xxxx-7c26d509a55d\nx-kms-apiname:Encrypt\nx-kms-apiversion:dkms-gcs-0.2\nx-kms-signaturemethod:RSA_PKCS1_SHA_256\n/
  3. Use the private key of the client key to generate a signature, and encode the signature in Base64.
    BPwBSB9NkxxuepqJ2zRtLT8jgv0FIAELJI2U79k8OPO7M7Y18Sz6+njTSwYWeIIQpJIJKx+mGBl/aR9opPbfQ+PhH+78rIPLJYNAJRvvaSUW/cRr4BMc1ByRXvuBmIcI81MQGutuU8uLnQYh9AURdklpqcW3ODz5OfsbuuxTGV17COoSO10tW3ltADumaMczFGTM0qCYi/pyh8p8i/gpwC3EXo540n5mqEmLexYIWb5/Fo+VonqZxZ3UuhZPw3vQ8uvqMGqvvw0xxKsblGuEdNSHcy/GYGRTFYugwOojZxd7TpADTqys+7SYaBWT38HnQLcH04DeD5rKkhRK7au8HQ==
  4. Send the HTTP request that contains the signature.
    POST / HTTP/1.1
    Date: Mon, 27 Sep 2021 11:47:26 GMT
    Host: kst-xxxx.cryptoservice.kms.aliyuncs.com
    Accept: application/x-protobuf
    Content-SHA256: AE71057543002AD513AB88D78509A1214192C09F20302C4BF8F59B7EB565****
    Content-Length: 40
    Content-Type: application/x-protobuf
    x-kms-acccesskeyid: KAAP.9c84ad54-d3c5-47c3-b0e7-7c26d509****
    x-kms-apiversion: dkms-gcs-0.2
    x-kms-apiname: Encrypt
    x-kms-signaturemethod: RSA_PKCS1_SHA_256
    Authorization: TOKEN BPwBSB9NkxxuepqJ2zRtLT8jgv0FIAELJI2U79k8OPO7M7Y18Sz6+njTSwYWeIIQpJIJKx+mGBl/aR9opPbfQ+PhH+78rIPLJYNAJRvvaSUW/cRr4BMc1ByRXvuBmIcI81MQGutuU8uLnQYh9AURdklpqcW3ODz5OfsbuuxTGV17COoSO10tW3ltADumaMczFGTM0qCYi/pyh8p8i/gpwC3EXo540n5mqEmLexYIWb5/Fo+VonqZxZ3UuhZPw3vQ8uvqMGqvvw0xxKsblGuEdNSHcy/GYGRTFYugwOojZxd7TpADTqys+7SYaBWT38HnQLcH04DeD5rKkhRK7au8HQ==
    
    <The encryption parameters are serialized to byte streams in the Protocol Buffers format.>