All Products
Search
Document Center

Key Management Service:Import key material into an asymmetric key

Last Updated:Mar 31, 2026

When you create an asymmetric key with an external key material origin, Key Management Service (KMS) does not generate key material for it. You must supply your own private key material and import it into the key. This is commonly referred to as Bring Your Own Key (BYOK).

Important

If your KMS instance of the hardware key management or software key management type does not allow key material import, or you receive an error during import, contact technical support.

Supported key management types

Not all key management types support asymmetric key material import. The following table shows what is supported.

Key management typeImport symmetric key materialImport asymmetric key material
Default key – Customer master keySupportedNot supported
Default key – Service keyNot supportedNot supported
Software-protected keySupportedSupported
Hardware-protected keySupportedNot supported

For more information about key management types, see Key management types and key specifications.

Usage notes

  • First import is permanent. The first time you import key material into a key, the key is permanently associated with that key material. You cannot import different key material into the same key afterward.

  • Reimport is supported. You can import the same key material into a key multiple times. If key material expires or is deleted, reimport the same key material to reuse the key.

  • Key material cannot be exported. After import, the key material cannot be retrieved from KMS. Store it in a secure location before importing.

Prerequisites

Before you begin, ensure that you have:

Import key material in the KMS console

The console-based import flow has four steps:

  1. Create an asymmetric key with an external key material origin.

  2. Download a wrapping public key and an import token.

  3. Encrypt your private key using the wrapping public key.

  4. Upload the encrypted key material and import token.

Step 1: Create an asymmetric key

Create an asymmetric key that uses an external key material origin. The steps differ slightly depending on your KMS instance type.

Software-protected key

  1. Log on to the KMS console. In the top navigation bar, select a region. In the left navigation pane, choose Resource > Keys.

  2. On the Customer Master Keys tab, select a software key management instance from the Instance ID drop-down list and click Create Key.

  3. In the Create Key panel, configure the following parameters and click OK.

    ParameterDescription
    Key typeSelect Asymmetric Key.
    Key specificationsSelect a specification: RSA_2048, RSA_3072, EC_P256, or EC_P256K.
    Key usageENCRYPT/DECRYPT: encrypts or decrypts data. SIGN/VERIFY: signs data or verifies a digital signature.
    Key aliasAn alias for the key. Allowed characters: letters, digits, underscores (_), hyphens (-), and forward slashes (/).
    Tag key, Tag valueTags to classify and manage keys. A tag key or value can be up to 128 characters (letters, digits, /, \, _, -, ., +, =, :, @, spaces). Tag keys cannot start with aliyun or acs:. Up to 20 tag key-value pairs per key.
    DescriptionAn optional description of the key.
    Policy settings (under Advanced settings)See Overview.
    Key material origin (under Advanced settings)Select External (Import Key Material). Read and select the acknowledgment: I understand the implications of using the external key materials.

Hardware-protected key

  1. Log on to the KMS console. In the top navigation bar, select a region. In the left navigation pane, choose Resource > Keys.

  2. On the Customer Master Keys tab, select a hardware key management instance from the Instance ID drop-down list and click Create Key.

  3. In the Create Key panel, configure the following parameters and click OK.

    ParameterDescription
    Key typeSelect Asymmetric Key.
    Key specificationsSelect a specification: RSA_2048, RSA_3072, RSA_4096, EC_P256, or EC_P256K.
    Key usageENCRYPT/DECRYPT: encrypts or decrypts data. SIGN/VERIFY: signs data or verifies a digital signature.
    Key aliasAn alias for the key. Allowed characters: letters, digits, underscores (_), hyphens (-), and forward slashes (/).
    Tag key, Tag valueTags to classify and manage keys. A tag key or value can be up to 128 characters (letters, digits, /, \, _, -, ., +, =, :, @, spaces). Tag keys cannot start with aliyun or acs:. Up to 20 tag key-value pairs per key.
    DescriptionAn optional description of the key.
    Policy settings (under Advanced settings)See Overview.
    Key material origin (under Advanced settings)Select External (Import Key Material). Read and select the acknowledgment: I understand the implications of using the external key materials.

Step 2: Download a wrapping public key and an import token

To import key material, you need two files from KMS:

  • Wrapping public key — used to encrypt your key material before upload.

  • Import token — authorizes the import operation.

  1. Find the key you created and click Details in the Actions column. On the Key Material tab, click Obtain Parameters for Import.

  2. In the Obtain Parameters to Import Key Material dialog box, select the Public Key Type and Encryption Algorithm, then click Next. Use the following table to determine the correct wrapping public key type and encryption algorithm for your key.

    Key material typeKey specificationWrapping public key typeEncryption algorithm
    RSA private key (software-protected)RSA_2048, RSA_3072RSA_2048RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD
    ECC private key (software-protected)EC_P256, EC_P256KRSA_2048RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD
    RSA private key (hardware-protected)RSA_2048, RSA_3072, RSA_4096RSA_2048RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD
    ECC private key (hardware-protected)EC_P256, EC_P256KRSA_2048RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD
    • Download both files and store them in a secure location.

      • DER format public key: file name is in the publickey_******.bin format.

      • PEM format public key: file name is in the publickey_******.pem format.

      • Import token: file name is in the token_******.txt format.

    Important
    • The import token is valid for 24 hours and can be reused within that period. After 24 hours, download a new import token and a new wrapping public key.

    • Always use the wrapping public key and import token from the same download. Do not mix files from different downloads.

    Step 3: Encrypt the private key

    You must encrypt the private key before uploading it. The encryption uses a double-wrapping scheme involving three keys.

    KeyAbbreviationTypeProviderDescription
    Target asymmetric keyTAKRSA or ECC key pairYour system, KMI, or HSMThe key pair you want to use. TAKpub is the public key; TAKpriv is the private key to import.
    Import wrapping keyIWKRSA key pairKMSThe key pair used to secure the import. IWKpub is the wrapping public key you downloaded.
    Ephemeral symmetric keyESKAES-256 (or SM4)Your systemA temporary symmetric key that encrypts TAKpriv. Destroy it immediately after use.

    Format requirement for TAKpriv:

    Encode the private key according to its type (RSA: RFC 3447; ECC: RFC 5915), then convert it to PKCS #8 format (RFC 5208). The final output must be in DER encoding.

    Encryption steps:

    1. Prepare TAKpriv in PKCS #8 DER format. If you already have the private key in this format, skip this step.

    2. Generate an AES-256 ESK (32 random bytes).

    3. Encrypt the ESK with IWKpub using RSAES-OAEP (SHA-256 for both the hash and MGF1). The result is Cipher(ESK).

    4. Encrypt TAKpriv with the ESK using AES-256 ECB mode with PKCS #7 padding. The result is Cipher(TAKpriv).

    5. Concatenate the two ciphertexts in the order Cipher(ESK) || Cipher(TAKpriv), then Base64-encode the result. This is your encrypted key material.

    Example: encrypt an RSA_2048 private key with OpenSSL

    # Step 1: Generate an RSA_2048 private key for TAK and convert it to PKCS #8 DER format
    openssl genrsa -out TakPrivPkcs1.pem 2048
    openssl pkcs8 -topk8 -inform PEM -in TakPrivPkcs1.pem -outform der -nocrypt -out TakPrivPkcs8.bin
    
    # Step 2: Generate an AES-256 ESK (32 bytes)
    openssl rand -out EskAes256.bin 32
    
    # Step 3: Encrypt the ESK with the IWK public key using RSAES-OAEP (SHA-256)
    # Replace PublicKey.pem with the wrapping public key file you downloaded from the KMS console.
    openssl pkeyutl -encrypt -pubin -inkey PublicKey.pem \
      -in EskAes256.bin \
      -pkeyopt rsa_padding_mode:oaep \
      -pkeyopt rsa_oaep_md:sha256 \
      -pkeyopt rsa_mgf1_md:sha256 \
      -out CipherEsk.bin
    
    # Step 4: Encrypt TAKpriv with the ESK using AES-256 ECB + PKCS #7 padding
    xxd -l 32 -c 32 -ps EskAes256.bin | xargs -I {} openssl enc -aes-256-ecb -e -K {} \
      -in TakPrivPkcs8.bin -nosalt -out CipherTakPriv.bin
    
    # Step 5: Concatenate and Base64-encode the result
    cat CipherEsk.bin CipherTakPriv.bin > EncryptedKeyMaterial.bin
    openssl enc -e -base64 -A -in EncryptedKeyMaterial.bin -out EncryptedKeyMaterial_base64.txt

    The file EncryptedKeyMaterial_base64.txt contains the encrypted key material to upload in the next step.

    Step 4: Import key material

    1. On the key details page, click Import Key Material.

    2. In the Import Wrapped Key Material dialog box, configure the following parameters and click OK.

      ParameterDescription
      Wrapped key materialUpload the encrypted key material file generated in Step 3.
      Import tokenUpload the import token file downloaded in Step 2.
      Key material expired onSelect Never Expire or specify an expiration time. If you set an expiration time, KMS deletes the key material when it expires, and the key becomes unavailable until you reimport the same key material.

    After import, the key status changes from Pending Import to Enabling.

    Import key material using Alibaba Cloud SDK

    The following Java example shows how to create an external asymmetric key in KMS and import key material using the Alibaba Cloud SDK.RSA or ECC

    Credentials are read from environment variables. Store your AccessKey ID and AccessKey Secret in ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET instead of hardcoding them in your project.

    All examples use the RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD or SM2PKE_SM4_ECB algorithm to encrypt the ephemeral symmetric key before assembling the final key material payload.

    import java.security.InvalidAlgorithmParameterException;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.PrivateKey;
    import java.security.Provider;
    import java.security.PublicKey;
    import java.security.SecureRandom;
    import java.security.interfaces.ECPrivateKey;
    import java.security.spec.ECGenParameterSpec;
    import java.security.spec.MGF1ParameterSpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Random;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.OAEPParameterSpec;
    import javax.crypto.spec.PSource.PSpecified;
    import javax.crypto.spec.SecretKeySpec;
    import javax.xml.bind.DatatypeConverter;
    
    import com.aliyuncs.AcsRequest;
    import com.aliyuncs.AcsResponse;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    import com.aliyuncs.http.FormatType;
    import com.aliyuncs.http.MethodType;
    import com.aliyuncs.http.ProtocolType;
    import com.aliyuncs.kms.model.v20160120.CreateKeyRequest;
    import com.aliyuncs.kms.model.v20160120.CreateKeyResponse;
    import com.aliyuncs.kms.model.v20160120.GetParametersForImportRequest;
    import com.aliyuncs.kms.model.v20160120.GetParametersForImportResponse;
    import com.aliyuncs.kms.model.v20160120.ImportKeyMaterialRequest;
    import com.aliyuncs.kms.model.v20160120.ImportKeyMaterialResponse;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.profile.IClientProfile;
    import org.apache.commons.lang3.tuple.Pair;
    import org.bouncycastle.asn1.gm.GMNamedCurves;
    import org.bouncycastle.asn1.x9.X9ECParameters;
    import org.bouncycastle.crypto.engines.SM2Engine;
    import org.bouncycastle.crypto.params.ECDomainParameters;
    import org.bouncycastle.crypto.params.ECPublicKeyParameters;
    import org.bouncycastle.crypto.params.ParametersWithRandom;
    import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    public class BringYourOwnAsymmetricKeySample {
        static String regionId = "cn-hangzhou";
        static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        static String dedicatedKmsInstanceId = "*** Provide your DedicatedKmsInstanceId ***";
        DefaultAcsClient kmsClient;
        private final String SM2PKE_SM4_ECB = "SM2PKE_SM4_ECB";
        private final String RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD = "RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD";
        private static Provider BC = new BouncyCastleProvider();
        private static X9ECParameters x9ECParameters = GMNamedCurves.getByName("sm2p256v1");
        private static ECDomainParameters ecDomainParameters = new ECDomainParameters(x9ECParameters.getCurve(), x9ECParameters.getG(), x9ECParameters.getN());
        static {
            java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        }
    
        public static void main(String[] args) {
            // Initialize Alibaba Cloud SDK.
            DefaultAcsClient client = getClientForPublicEndpoint(regionId, accessKeyId, accessKeySecret);
            BringYourOwnAsymmetricKeySample sample = new BringYourOwnAsymmetricKeySample(client);
    
            // Create and import an external EC_SM2 key.
            sample.doByok("EC_SM2", "EC_SM2", sample.SM2PKE_SM4_ECB, "SM4");
            // Create and import an external EC_P256 key.
            sample.doByok("EC_P256", "RSA_2048", sample.RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD, "AES_256");
            // Create and import an external RSA key.
            sample.doByok("RSA_2048", "RSA_2048", sample.RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD, "AES_256");
        }
    
    
        public static DefaultAcsClient getClientForPublicEndpoint(String regionId, String accessKeyId, String accessKeySecret) {
            /**
             * Construct an Aliyun Client:
             * Set RegionId, AccessKeyId and AccessKeySecret
             */
            IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            return client;
        }
    
        public BringYourOwnAsymmetricKeySample(DefaultAcsClient kmsClient) {
            this.kmsClient = kmsClient;
        }
    
        public void doByok(String targetKeySpec, String wrappingKeySpec, String wrappingAlgorithm, String ephemeralKeySpec) {
            try {
                // Create an external ECC key.
                CreateKeyResponse.KeyMetadata keyMetadata = this.createExternalKeyInDkms(dedicatedKmsInstanceId, targetKeySpec, "SIGN/VERIFY");
                String keyId = keyMetadata.getKeyId();
                // Obtain the parameters that are used to import key material.
                GetParametersForImportResponse parametersForImportResponse = this.getParametersForImport(keyId, wrappingKeySpec,
                    wrappingAlgorithm);
                String importToken = parametersForImportResponse.getImportToken();
                String publicKeyBase64 = parametersForImportResponse.getPublicKey();
                // Create an ESK.
                byte[] ephemeralSymmetricKeyPlaintext = this.generateEphemeralSymmetricKey(ephemeralKeySpec);
                // Create a TAK.
                byte[] targetAsymmetricKeyPlaintext = this.generateTargetAsymmetricKey(targetKeySpec);
                // Use the public key of an IWK to encrypt the ESK.
                byte[] ephemeralSymmetricKeyCipher = this.encryptEphemeralSymmetricKey(publicKeyBase64,
                    wrappingAlgorithm, ephemeralSymmetricKeyPlaintext);
                // Use the ESK to encrypt the TAK.
                byte[] targetAsymmetricKeyCipher = this.encryptTargetAsymmetricKey(ephemeralSymmetricKeyPlaintext, targetAsymmetricKeyPlaintext,
                    wrappingAlgorithm);
                // Assemble the encrypted key material: Cipher(ESK) || Cipher(TAKpriv).
                byte[] encryptedKeyMaterial = new byte[ephemeralSymmetricKeyCipher.length + targetAsymmetricKeyCipher.length];
                System.arraycopy(ephemeralSymmetricKeyCipher, 0, encryptedKeyMaterial, 0, ephemeralSymmetricKeyCipher.length);
                System.arraycopy(targetAsymmetricKeyCipher, 0, encryptedKeyMaterial, ephemeralSymmetricKeyCipher.length, targetAsymmetricKeyCipher.length);
                String encryptedKeyMaterialBase64 =  DatatypeConverter.printBase64Binary(encryptedKeyMaterial);
                // Import the key material.
                this.importKeyMaterial(keyId, encryptedKeyMaterialBase64, importToken, 0L);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private GetParametersForImportResponse getParametersForImport(String keyId, String keySpec, String algorithm) throws Exception {
            GetParametersForImportRequest request = new GetParametersForImportRequest();
            request.setAcceptFormat(FormatType.JSON);
            request.setMethod(MethodType.POST);
            request.setProtocol(ProtocolType.HTTPS);
            request.setKeyId(keyId);
            request.setWrappingKeySpec(keySpec);
            request.setWrappingAlgorithm(algorithm);
            GetParametersForImportResponse resp;
            try {
                resp = this.getAcsResponseWithRetry(request);
            } catch (Exception e) {
                throw e;
            }
            return resp;
        }
    
        private CreateKeyResponse.KeyMetadata createExternalKeyInDkms(String dedicatedKmsInstance, String keySpec, String keyUsage) throws Exception {
            CreateKeyRequest request = new CreateKeyRequest();
            // Create an external key.
            request.setOrigin("EXTERNAL");
            request.setKeyStoreId(dedicatedKmsInstance);
            request.setKeySpec(keySpec);
            request.setKeyUsage(keyUsage);
    
            request.setProtocol(ProtocolType.HTTPS);
            request.setAcceptFormat(FormatType.JSON);
            request.setMethod(MethodType.POST);
            CreateKeyResponse.KeyMetadata ret = null;
            String requestId = null;
            try {
                CreateKeyResponse response = getAcsResponseWithRetry(request);
                ret = response.getKeyMetadata();
                requestId = response.getRequestId();
            } catch (Exception e) {
                throw e;
            }
            return Pair.of(ret, requestId).getKey();
        }
    
        private <T extends AcsResponse> T getAcsResponseWithRetry(AcsRequest<T> request) throws ServerException,
            ClientException {
            String expStr = "Retry Max Times";
            for (int i = 0; i < 3; i++) {
                try {
                    T resp = this.kmsClient.getAcsResponse(request);
                    if (resp == null) {
                        throw new ClientException("Get a null response");
                    }
                    return resp;
                } catch (ServerException e) {
                    throw e;
                } catch (ClientException e) {
                    expStr = e.toString();
                  //need retry
                    if (expStr.contains("SDK.ServerUnreachable")) {
                        continue;
                    }
                    throw e;
                }
            }
            throw new ClientException(expStr);
        }
    
        private byte[] generateEphemeralSymmetricKey(String ephemeralSymmetricKeySpec) throws Exception {
           // If the ESK is of the AES_256 type, set the length to 32 bits.
           int ephemeralSymmetricKeyLength = 32;
            if ("SM4".equals(ephemeralSymmetricKeySpec)) {
                ephemeralSymmetricKeyLength = 16;
            }
            byte[] key = new byte[32];
            new Random().nextBytes(key);
    
            return key;
        }
    
        private byte[] generateTargetAsymmetricKey(String keySpec) throws Exception {
            PrivateKey privateKey = null;
            // Create an SM2 key and obtain the value of the D parameter for the private key.
            if ("EC_SM2".equals(keySpec)) {
                ECPrivateKey ecPrivateKey = (ECPrivateKey)generateSm2KeyPair().getPrivate();
                byte[] dT = ecPrivateKey.getS().toByteArray();
                byte[] d = new  byte[32];
                if (dT.length == 33) {
                    System.arraycopy(dT, 1, d, 0, 32);
                }
                return dT.length == 32 ? dT : d;
            }
    
            // Generate an RSA or ECC private key.
            if (keySpec.contains("RSA")) {
                String[] keySpecAttrs = keySpec.split("_");
                int bits = Integer.parseInt(keySpecAttrs[keySpecAttrs.length - 1]);
                privateKey = generateRsaKeyPair(bits).getPrivate();
            } else if  (keySpec.contains("EC")) {
                if (keySpec.contains("P256K")) {
                    // Generate an EC_P256K private key.
                    privateKey  = generateEccKeyPair("secp256k1").getPrivate();
                } else {
                    // Generate an EC_P256 private key.
                    privateKey=   generateEccKeyPair("secp256r1").getPrivate();
                }
            }
            if (privateKey != null) {
                // Return the private key in the PKCS #8 format.
                return  privateKey.getEncoded();
            }
            return null;
        }
    
        private  KeyPair generateEccKeyPair(String keySpec)
            throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
            ECGenParameterSpec ecSpec = new ECGenParameterSpec(keySpec);
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
            keyPairGenerator.initialize(ecSpec, new SecureRandom());
            return keyPairGenerator.generateKeyPair();
        }
        private  KeyPair generateRsaKeyPair(int length) throws Exception {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(length);
            return keyGen.genKeyPair();
        }
    
        private KeyPair generateSm2KeyPair() throws Exception {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC", "BC");
            keyGen.initialize(new ECGenParameterSpec("sm2p256v1"), new SecureRandom());
            return keyGen.genKeyPair();
        }
    
    
        private byte[] encryptEphemeralSymmetricKey (String publicKeyBase64, String wrappingAlgorithm, byte[] ephemeralSymmetricKeyPlaintext) throws Exception {
            PublicKey publickey = null;
            byte[] enchbk = null;
            if ("RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD".equals(wrappingAlgorithm)) {
                publickey = parseDerPublicKey("RSA", publicKeyBase64);
                Cipher oaepFromAlgo = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
                OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), PSpecified.DEFAULT);
                oaepFromAlgo.init(Cipher.ENCRYPT_MODE, publickey, oaepParams);
                enchbk = oaepFromAlgo.doFinal(ephemeralSymmetricKeyPlaintext);
            } else if ("SM2PKE_SM4_ECB".equals(wrappingAlgorithm)) {
                publickey = parseDerPublicKey("EC", publicKeyBase64, BC);
                BCECPublicKey localECPublicKey = (BCECPublicKey) publickey;
                ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(localECPublicKey.getQ(), ecDomainParameters);
                SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
                sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters));
                enchbk = sm2Engine.processBlock(ephemeralSymmetricKeyPlaintext, 0, ephemeralSymmetricKeyPlaintext.length);
    
            } else {
                throw new Exception("Invalid wrappingAlgorithm");
            }
            return enchbk;
        }
    
        private PublicKey parseDerPublicKey(String keyType, String pemKey) throws Exception {
            byte[] derKey = DatatypeConverter.parseBase64Binary(pemKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(derKey);
            return KeyFactory.getInstance(keyType).generatePublic(keySpec);
        }
        private PublicKey parseDerPublicKey(String keyType, String pemKey, Provider provider) throws Exception {
            byte[] derKey = DatatypeConverter.parseBase64Binary(pemKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(derKey);
            return KeyFactory.getInstance(keyType, provider).generatePublic(keySpec);
        }
    
        private byte[] encryptTargetAsymmetricKey (byte[] secretKey, byte[] targetAsymmetricKeyPlaintext, String wrappingAlgorithm)
            throws Exception {
            if ("RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD".equals(wrappingAlgorithm)) {
                SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "AES");
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
                return cipher.doFinal(targetAsymmetricKeyPlaintext);
            } else if ("SM2PKE_SM4_ECB".equals(wrappingAlgorithm)) {
                SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "SM4");
                Cipher cipher = Cipher.getInstance("SM4/ECB/NoPadding");
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
                return cipher.doFinal(targetAsymmetricKeyPlaintext);
            }
    
            throw new Exception("Invalid WrappingAlgorithm");
        }
    
        private boolean importKeyMaterial(
            String keyId,
            String material,
            String token,
            Long expire
        ) throws Exception {
            ImportKeyMaterialRequest req = newImportKeyMaterialRequest(
                keyId, material, token, expire);
            try {
                ImportKeyMaterialResponse resp = this.getAcsResponseWithRetry(req);
            } catch (Exception e) {
                throw e;
            }
            return true;
        }
    
        private ImportKeyMaterialRequest newImportKeyMaterialRequest(
            String keyId,
            String material,
            String token,
            Long expire
        ) {
            ImportKeyMaterialRequest request = new ImportKeyMaterialRequest();
            request.setAcceptFormat(FormatType.JSON);
            request.setMethod(MethodType.POST);
            request.setProtocol(ProtocolType.HTTPS);
            request.setEncryptedKeyMaterial(material);
            request.setImportToken(token);
            request.setKeyId(keyId);
            request.setKeyMaterialExpireUnix(expire);
            return request;
        }
    }

    Replace the following placeholders:

    PlaceholderDescription
    * Provide your DedicatedKmsInstanceId *The ID of your dedicated KMS instance
    cn-hangzhouThe region where your KMS instance is deployed

    FAQ

    Can I delete key material?

    Yes. After key material is deleted or expires, the key becomes unavailable until you reimport the same key material.

    To delete key material directly:

    • KMS console: On the key details page, click the Key Material tab and then click Delete Key Material.

    • KMS API: Call the DeleteKeyMaterial operation. This deletes the key material but not the key itself.

    To set automatic deletion, specify an expiration time when importing. KMS deletes the key material when the expiration time is reached.

    How do I reimport the same key material?

    If key material has expired or been deleted, reimport the same key material to restore the key.

    1. On the key details page, click the Key Material tab and then click Delete Key Material to clear the expired key material.

    2. Download a new wrapping public key and import token (see Step 2). The wrapping procedure does not affect the content of the key material, so you can use a different wrapping public key and algorithm.

    3. Encrypt the key material using the new wrapping public key (see Step 3). The key material itself must be identical to the original.

    4. Upload the encrypted key material with the new import token (see Step 4).

    How do I check the key material origin of a key?

    • KMS console: On the Customer Master Keys tab, find the key and click Details in the Actions column. Check the Key Material Origin field on the details page.

    • KMS API: Call DescribeKey. If the Origin field is EXTERNAL, the key material was imported. If it is Aliyun_KMS, KMS generated the key material.

    Does key rotation work with imported key material?

    Key rotation support depends on the key type:

    • Software-protected symmetric keys with imported key material: only immediate manual rotation is supported. Automatic periodic rotation is not supported. For details, see Rotate a Bring-Your-Own-Key (BYOK) key.

    • Software-protected asymmetric keys with imported key material: rotation is not supported.

    • Hardware-protected keys (symmetric and asymmetric) with imported key material: rotation is not supported.

    What's next

    References