CMK description and classification

Customer master keys (CMKs) are the basic resources of KMS. CMKs are composed of key IDs, basic metadata (such as key state) and key materials used to encrypt and decrypt data. In normal circumstances, KMS generates key material when you perform CreateKey. You can choose to create a key from external key materials. In such a case, KMS does not generate key material for the CMK you create and you can import your own key material to the CMK. You can use DescribeKey to determine the source of the key material. When the Origin in the KeyMetadata is Aliyun_KMS, this indicates that the key material was generated by KMS and can be referred to as the Normal Key. If the Origin is EXTERNAL, this indicates that the key material was imported from an external source and can be referred to as the External Key.


When you select an external key material source and use the key material you imported, you must note the following:

  • You must be sure that the random source used to generate the key material complies with requirements.
  • You must ensure the reliability of the key material.
    • KMS ensures the high availability of imported key materials, but cannot ensure that imported key material has the same reliability as the key material generated by KMS.
    • You can directly use the DeleteKeyMaterial operation to delete the imported key material. Or you can set an expiration time to automatically delete the imported key material after it expires (without deleting CMKs). The key material generated by KMS cannot be directly deleted. Instead, you can use the ScheduleKeyDeletion operation to delete the key material along with CMK after 7 to 30 days.
    • After you delete the imported key material, you can re-import the same key material to make the relevant CMK available again. Therefore, you need to independently save a copy of the key material.
  • Each CMK can only have one imported key material. Once you import the key material to a CMK, this CMK is bound to this key material. Even if this key material expires or is deleted, you cannot import any other key material for the CMK. If you need to rotate a CMK that uses the external key material, you must create a new CMK and then import the new key material.
  • CMKs are independent. When you use one CMK to encrypt data, you cannot use another CMK to decrypt the data, even if these CMKs use the same key material.
  • You can only import 256-bit symmetric keys as key material.

How to import key material

  1. Create an external key

    First, you must create an External Key. To do this, go to the console’s key creation advanced options and select an external key material source, or send a request to the CreateKey API and specify the Origin parameter value as EXTERNAL. By choosing to create an external key, you indicate that your have read and understood the Note and How to import key material sections of this document.


    aliyuncli kms CreateKey --Origin EXTERNAL --Description "External key"
  2. Get import key material parameters

    After successfully creating an external key, before you import the key material, you must obtain the import key material parameters. You can obtain the import key material parameters on the console or by sending a request to the GetParametersForImport. The import key material parameters include a public key used to encrypt the key material and an import token.


    aliyuncli kms GetParametersForImport --KeyId 1339cb7d-54d3-47e0-b595-c7d3dba82b6f --WrappingAlgorithm RSAES_OAEP_SHA_1 --WrappingKeySpec RSA_2048
  3. Import key material

    The import key material operation can import key material for external keys that do not yet have key material. It can also re-import key material that has expired or been deleted, or reset the key material expiration time. The import token is bound to the public key used to encrypt key material. A single token can only be used to import the key material for the CMK specified at the time of generation. An import token is valid for 24 hours and can be used multiple times during this period. After the token expires, you must obtain a new import token and public encryption key.

    • First, use the public encryption key to encrypt the key material. The public encryption key is a 2,048-bit RSA public key. The encryption algorithm used must be consistent with that specified when obtaining the import key material parameters. Because the API returns the public encryption key in base64 encoding, you must first perform base64 decoding when using it. Currently, KMS supports the following encryption algorithms: RSAES_OAEP_SHA_1, RSAES_OAEP_SHA_256, and RSAES_PKCS1_V1_5.
    • After encryption, you must perform base64 encoding on the encrypted key material and then use this, along with the import token as GenerateDataKey parameters to import the key material to KMS.


    aliyuncli kms ImportKeyMaterial --KeyId 1339cb7d-54d3-47e0-b595-c7d3dba82b6f --EncryptedKeyMaterial xxx --ImportToken xxxx

Delete key material

  • After importing key material, you can use the external key just like a normal key. External keys differ from normal keys in that their key material can expire or be manually deleted. After the key material expires or is deleted, the key will no longer function and ciphertext data encrypted using this key cannot be decrypted unless you re-import the same key material
  • If a key enters the PendingDeletion state after its key material expires or is deleted, the key state does not change. Otherwise, the key state changes to PendingImport.
  • You can use the console or DeleteKeyMaterial to delete the key material.


aliyuncli kms DeleteKeyMaterial --KeyId xxxx

Operation examples

Use OPENSSL to encrypt and upload key material

  • Create an external key.
  • Generate the key material. The key material must be a 256-bit symmetric key. In this example, we use OPENSSL to generate a 32-byte random number.
    1.openssl rand -out KeyMaterial.bin 32
  • Get import key material parameters.
  • Encrypt key material.
  • First, you must perform base64 decoding on the public encryption key.
  • Then, encrypt the key material using the encryption algorithm (here, we use RSAES_OAEP_SHA_1).
  • Finally, perform base64 encoding on the encrypted key material and save it as a text file.
    openssl rand -out KeyMaterial.bin 32
    openssl enc -d -base64 -A -in PublicKey_base64.txt -out PublicKey.bin
    openssl rsautl -encrypt -in KeyMaterial.bin -oaep -inkey PublicKey.bin  -keyform DER  -pubin -out EncryptedKeyMaterial.bin
    openssl enc -e -base64 -A -in EncryptedKeyMaterial.bin -out EncryptedKeyMaterial_base64.txt
  • Upload the encrypted key material and import token.

Use JAVA SDK to encrypt and upload key material

//Uses the latest KMS JAVA SDK

import com.aliyuncs.kms.model.v20160120.*;
import com.aliyuncs.profile.DefaultProfile;

//KMS API encapsulation
public class KmsClient {
        DefaultAcsClient client;

        public KmsClient( String region_id, String ak, String secret) {
                DefaultProfile profile = DefaultProfile.getProfile(region_id, ak, secret);
                this.client = new DefaultAcsClient(profile);

        public CreateKeyResponse createKey() throws Exception {
                CreateKeyRequest request = new CreateKeyRequest();
                request.setOrigin("EXTERNAL"); //Creates an external key
                return this.client.getAcsResponse(request);
        //... Omitted, the remaining operations are the same as those in the API method.
import com.aliyuncs.kms.model.v20160120.*;
import KmsClient
import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource.PSpecified;
import java.util.Random;
import javax.xml.bind.DatatypeConverter;

public class CreateAndImportExample {
        public static void main(String[] args) {
                String regionId = "cn-hangzhou";
        String accessKeyId = "*** Provide your AccessKeyId ***";
        String accessKeySecret = "*** Provide your AccessKeySecret ***";
        KmsClient kmsclient = new KmsClient(regionId,accessKeyId,accessKeySecret);
        //Create External Key
        try {
                CreateKeyResponse keyResponse = kmsclient.createKey();
                String keyId = keyResponse.KeyMetadata.getKeyId();
                //Generates a 32-bit random number
                byte[] keyMaterial = new byte[32];
                new Random().nextBytes(keyMaterial);
                //Gets import key material parameters
                GetParametersForImportResponse paramResponse = kmsclient.getParametersForImport(keyId,"RSAES_OAEP_SHA_256");
                String importToekn = paramResponse.getImportToken();
                String encryptPublicKey = paramResponse.getPublicKey();
                //Performs base64 decoding on the public encryption key
                byte[] publicKeyDer = DatatypeConverter.parseBase64Binary(encryptPublicKey);
                //Parses the RSA public key
                KeyFactory keyFact = KeyFactory.getInstance("RSA");
                X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyDer);
                PublicKey publicKey = keyFact.generatePublic(spec);
                //Encrypts key material
                Cipher oaepFromAlgo = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
                String hashFunc = "SHA-256";
                OAEPParameterSpec oaepParams = new OAEPParameterSpec(hashFunc, "MGF1", new MGF1ParameterSpec(hashFunc), PSpecified.DEFAULT);
                oaepFromAlgo.init(Cipher.ENCRYPT_MODE, publicKey, oaepParams);
                byte[] cipherDer = oaepFromAlgo.doFinal(keyMaterial);
                //You must perform base64 encoding on the encrypted key material
                String encryptedKeyMaterial = DatatypeConverter.printBase64Binary(cipherDer);
                //Imports key material
                Long expireTimestamp = 1546272000L; //Unix timestamp, precise to the second, 0 indicates no expiration
                        kmsClient.importKeyMaterial(keyId,encryptedKeyMaterial, expireTimestamp);
        } catch(Exception e) {
                //... Omitted