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).
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 type | Import symmetric key material | Import asymmetric key material |
|---|---|---|
| Default key – Customer master key | Supported | Not supported |
| Default key – Service key | Not supported | Not supported |
| Software-protected key | Supported | Supported |
| Hardware-protected key | Supported | Not 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:
A KMS instance that is purchased and enabled. For more information, see Purchase and enable a KMS instance.
Import key material in the KMS console
The console-based import flow has four steps:
Create an asymmetric key with an external key material origin.
Download a wrapping public key and an import token.
Encrypt your private key using the wrapping public key.
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
Log on to the KMS console. In the top navigation bar, select a region. In the left navigation pane, choose Resource > Keys.
On the Customer Master Keys tab, select a software key management instance from the Instance ID drop-down list and click Create Key.
In the Create Key panel, configure the following parameters and click OK.
Parameter Description Key type Select Asymmetric Key. Key specifications Select a specification: RSA_2048, RSA_3072, EC_P256, or EC_P256K. Key usage ENCRYPT/DECRYPT: encrypts or decrypts data. SIGN/VERIFY: signs data or verifies a digital signature. Key alias An alias for the key. Allowed characters: letters, digits, underscores ( _), hyphens (-), and forward slashes (/).Tag key, Tag value Tags to classify and manage keys. A tag key or value can be up to 128 characters (letters, digits, /,\,_,-,.,+,=,:,@, spaces). Tag keys cannot start withaliyunoracs:. Up to 20 tag key-value pairs per key.Description An 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
Log on to the KMS console. In the top navigation bar, select a region. In the left navigation pane, choose Resource > Keys.
On the Customer Master Keys tab, select a hardware key management instance from the Instance ID drop-down list and click Create Key.
In the Create Key panel, configure the following parameters and click OK.
Parameter Description Key type Select Asymmetric Key. Key specifications Select a specification: RSA_2048, RSA_3072, RSA_4096, EC_P256, or EC_P256K. Key usage ENCRYPT/DECRYPT: encrypts or decrypts data. SIGN/VERIFY: signs data or verifies a digital signature. Key alias An alias for the key. Allowed characters: letters, digits, underscores ( _), hyphens (-), and forward slashes (/).Tag key, Tag value Tags to classify and manage keys. A tag key or value can be up to 128 characters (letters, digits, /,\,_,-,.,+,=,:,@, spaces). Tag keys cannot start withaliyunoracs:. Up to 20 tag key-value pairs per key.Description An 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.
Find the key you created and click Details in the Actions column. On the Key Material tab, click Obtain Parameters for Import.
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 type Key specification Wrapping public key type Encryption algorithm RSA private key (software-protected) RSA_2048, RSA_3072 RSA_2048 RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD ECC private key (software-protected) EC_P256, EC_P256K RSA_2048 RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD RSA private key (hardware-protected) RSA_2048, RSA_3072, RSA_4096 RSA_2048 RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD ECC private key (hardware-protected) EC_P256, EC_P256K RSA_2048 RSAES_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_******.binformat.PEM format public key: file name is in the
publickey_******.pemformat.Import token: file name is in the
token_******.txtformat.
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.
| Key | Abbreviation | Type | Provider | Description |
|---|---|---|---|---|
| Target asymmetric key | TAK | RSA or ECC key pair | Your system, KMI, or HSM | The key pair you want to use. TAKpub is the public key; TAKpriv is the private key to import. |
| Import wrapping key | IWK | RSA key pair | KMS | The key pair used to secure the import. IWKpub is the wrapping public key you downloaded. |
| Ephemeral symmetric key | ESK | AES-256 (or SM4) | Your system | A 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:
Prepare TAKpriv in PKCS #8 DER format. If you already have the private key in this format, skip this step.
Generate an AES-256 ESK (32 random bytes).
Encrypt the ESK with IWKpub using RSAES-OAEP (SHA-256 for both the hash and MGF1). The result is
Cipher(ESK).Encrypt TAKpriv with the ESK using AES-256 ECB mode with PKCS #7 padding. The result is
Cipher(TAKpriv).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.txtThe file EncryptedKeyMaterial_base64.txt contains the encrypted key material to upload in the next step.
Step 4: Import key material
On the key details page, click Import Key Material.
In the Import Wrapped Key Material dialog box, configure the following parameters and click OK.
Parameter Description Wrapped key material Upload the encrypted key material file generated in Step 3. Import token Upload the import token file downloaded in Step 2. Key material expired on Select 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.
For credential configuration, see Manage access credentials.
For environment variable setup, see Configure environment variables in Linux, macOS, and Windows.
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:
| Placeholder | Description |
|---|---|
* Provide your DedicatedKmsInstanceId * | The ID of your dedicated KMS instance |
cn-hangzhou | The 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.
On the key details page, click the Key Material tab and then click Delete Key Material to clear the expired key material.
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.
Encrypt the key material using the new wrapping public key (see Step 3). The key material itself must be identical to the original.
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
Originfield isEXTERNAL, the key material was imported. If it isAliyun_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.