This topic describes how to import and delete external key material.

Prerequisites

An Alibaba Cloud account is created. To create an Alibaba Cloud account, visit the account registration page.

Background information

Customer master keys (CMKs) are basic resources of KMS. A CMK is composed of a key ID, basic metadata (such as key state), and key material that is used to encrypt and decrypt data. By default, when you call the CreateKey operation to create a CMK, you can set the Origin parameter to Aliyun_KMS. In this case, KMS generates key material. For more information about the CreateKey operation, see CreateKey. If you set the Origin parameter to EXTERNAL, you must import external key material to the CMK. In this case, KMS does not create key material. You can call the DescribeKey operation to check the key material source of an existing CMK. For more information about the DescribeKey operation, see DescribeKey.
  • If the value of Origin in KeyMetadata is Aliyun_KMS, the key material is generated by KMS. In this case, the CMK is considered to be a normal key.
  • If the value of Origin is EXTERNAL, the key material is imported from an external source. In this case, the CMK is considered to be an external key.
Before you import external key material, take note of the following points:
  • Make sure that the source of randomness from which the key material is generated meets security requirements.
  • Make sure that the key material is reliable.
    • KMS ensures the high availability of imported key material. However, it cannot ensure that the imported key material has the same reliability as the key material generated by KMS.
    • You can call the DeleteKeyMaterial operation to delete the key material that you have imported. You can also set an expiration time to automatically delete the key material after it expires. The CMK is not deleted. For more information about the DeleteKeyMaterial operation, see DeleteKeyMaterial. To delete key material generated by KMS, you can only call the ScheduleKeyDeletion operation to specify a waiting period of 7 to 30 days for deleting the CMK. The key material is deleted with the relevant CMK after the waiting period ends. For more information about the ScheduleKeyDeletion operation, see ScheduleKeyDeletion.
    • After you delete the imported key material, you can re-import the same key material to make the relevant CMK available again. Therefore, we recommend that you save a copy of the key material.
  • Key material is unique for each CMK. When you import key material into a CMK, the CMK is associated with that key material. Even after the key material expires or is deleted, you cannot import different key material into that CMK. If you need to rotate a CMK that uses external key material, you must create a new CMK and then import new key material.
  • CMKs are independent. You cannot use a CMK to decrypt data that is encrypted by using another CMK, even if the two CMKs use the same key material.
  • The key material to be imported must be a 256-bit symmetric key.

Import key material

  1. Create an external key.
    You can use one of the following methods to create an external key:
    • Method 1: Log on to the KMS console and click Create Key. In the Advanced section of the Create Key dialog box, set Key Material Source to External. For more information, see Create a CMK.
    • Method 2: Call the CreateKey operation. Set Origin to EXTERNAL.
      aliyun kms CreateKey --Origin EXTERNAL --Description "External key"
  2. Obtain parameters that are used to import key material.
    The parameters include a public key that is used to encrypt the key material and an import token. You can use one of the following methods to obtain the parameters:
    • Method 1: Obtain the parameters in the KMS console.
    • Method 2: Call the GetParametersForImport operation to obtain the parameters. For more information about the GetParametersForImport operation, see GetParametersForImport.
      aliyun kms GetParametersForImport --KeyId 1339cb7d-54d3-47e0-b595-c7d3dba8**** --WrappingAlgorithm RSAES_OAEP_SHA_1 --WrappingKeySpec RSA_2048
  3. Import key material.
    • You can import key material into an external key that never has key material. You can also reset the expiration time of key material or re-import key material that has expired or been deleted.
    • Each import token is bound to a public key that is used to encrypt key material. A CMK is specified when an import token is generated. The import token can only be used to import key material into the specified CMK.
    • The lifecycle of an import token is 24 hours. It can be used repeatedly within this period. After it expires, you must obtain a new import token and a new public key.
    1. Use the public key to encrypt the key material.
      The public key is a 2048-bit Rivest-Shamir-Adleman (RSA) public key. The encryption algorithm must be consistent with that specified when you obtain the import parameters. Because the public key returned when you call the GetParametersForImport operation is Base64 encoded, you must first decode the public key. Currently, KMS supports the following encryption algorithms: RSAES_OAEP_SHA_1, RSAES_OAEP_SHA_256, and RSAES_PKCS1_V1_5.
    2. Base64 encode the encrypted key material.
    3. Call the ImportKeyMaterial operation to import the encoded key material and the import token to KMS.
      For more information about the ImportKeyMaterial operation, see ImportKeyMaterial.
      aliyun kms ImportKeyMaterial --KeyId 1339cb7d-54d3-47e0-b595-c7d3dba8**** --EncryptedKeyMaterial xxx --ImportToken xxxx
  4. Delete key material.

    After you import key material into an external key, you can use the external key just like a normal key. The only difference is that the key material of an external key may expire and can be deleted independently. After the key material of an external key expires or is deleted, the external key can no longer be used, and the ciphertext encrypted by using this external key cannot be decrypted. To enable the external key and related decryption again, you must re-import the same key material.

    If an external key is in the Pending Deletion state before its key material expires or is deleted, the key state does not change after the key material expires or is deleted. Otherwise, the key state changes to Pending Import after the key material expires or is deleted.

    You can use one of the following methods to delete key material:
    • Method 1: Delete the key material in the KMS console.
    • Method 2: Call the DeleteKeyMaterial operation to delete the key material. For more information about the DeleteKeyMaterial operation, see DeleteKeyMaterial.
      aliyun kms DeleteKeyMaterial --KeyId 1339cb7d-54d3-47e0-b595-c7d3dba8****      

Use OpenSSL to encrypt and upload key material

  1. Create an external key.
  2. Generate key material.
    The key material must be a 256-bit symmetric key. In this example, OpenSSL is used to generate a 32-byte random number.
    openssl rand -out KeyMaterial.bin 32
  3. Obtain parameters that are used to import the key material.
  4. Encrypt the key material.
    1. Base64 decode the public key that is used to encrypt the key material.
    2. Use an encryption algorithm such as RSAES_OAEP_SHA_1 to encrypt the key material.
    3. Base64 encode 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
    4. Upload the encrypted key material and the import token.

Example

Use SDK for Java to encrypt and upload key material

//Use the latest KMS SDK for Java.
//KmsClient.java

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"); //Create an external key.
                return this.client.getAcsResponse(request);
        }
        //... Omitted. The remaining operations are the same as those in the API method.
}
//example.java
import com.aliyuncs.kms.model.v20160120.*;
import KmsClient
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.MGF1ParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource.PSpecified;
import java.security.spec.X509EncodedKeySpec;
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();
                //Generate a 32-bit random number.
                byte[] keyMaterial = new byte[32];
                new Random().nextBytes(keyMaterial);
                //Obtain parameters that are used to import the key material.
                GetParametersForImportResponse paramResponse = kmsclient.getParametersForImport(keyId,"RSAES_OAEP_SHA_256");
                String importToekn = paramResponse.getImportToken();
                String encryptPublicKey = paramResponse.getPublicKey();
                //Base64 decode the public key.
                byte[] publicKeyDer = DatatypeConverter.parseBase64Binary(encryptPublicKey);
                //Use RSA to parse the public key.
                KeyFactory keyFact = KeyFactory.getInstance("RSA");
                X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyDer);
                PublicKey publicKey = keyFact.generatePublic(spec);
                //Encrypt the 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);
                //Base64 encode the encrypted key material.
                String encryptedKeyMaterial = DatatypeConverter.printBase64Binary(cipherDer);
                //Import the key material.
                Long expireTimestamp = 1546272000L; //Unix timestamp, precise to the second. 0 indicates that the key material does not expire.
                        kmsClient.importKeyMaterial(keyId,encryptedKeyMaterial, expireTimestamp);
        } catch(Exception e) {
                //... Omitted.
        }
        }
}