Saat Anda membuat kunci asimetris dengan origin bahan kunci eksternal, Key Management Service (KMS) tidak menghasilkan bahan kunci untuknya. Anda harus menyediakan sendiri bahan kunci privat dan mengimpornya ke dalam kunci tersebut. Hal ini umumnya dikenal sebagai Bring Your Own Key (BYOK).
Jika instans KMS Anda bertipe hardware key management atau software key management tidak mengizinkan impor bahan kunci, atau Anda menerima error selama proses impor, hubungi dukungan teknis.
Tipe manajemen kunci yang didukung
Tidak semua tipe manajemen kunci mendukung impor bahan kunci asimetris. Tabel berikut menunjukkan dukungan yang tersedia.
| Tipe manajemen kunci | Impor bahan kunci simetris | Impor bahan kunci asimetris |
|---|---|---|
| Kunci default – Customer master key | Didukung | Tidak didukung |
| Kunci default – Service key | Tidak didukung | Tidak didukung |
| Kunci terproteksi perangkat lunak | Didukung | Didukung |
| Kunci terproteksi perangkat keras | Didukung | Tidak didukung |
Untuk informasi lebih lanjut tentang tipe manajemen kunci, lihat Tipe manajemen kunci dan spesifikasi kunci.
Catatan penggunaan
Impor pertama bersifat permanen. Saat pertama kali Anda mengimpor bahan kunci ke dalam suatu kunci, kunci tersebut secara permanen dikaitkan dengan bahan kunci tersebut. Anda tidak dapat mengimpor bahan kunci yang berbeda ke dalam kunci yang sama setelahnya.
Reimpor didukung. Anda dapat mengimpor bahan kunci yang sama ke dalam suatu kunci beberapa kali. Jika bahan kunci kedaluwarsa atau dihapus, reimpor bahan kunci yang sama untuk menggunakan kembali kunci tersebut.
Bahan kunci tidak dapat diekspor. Setelah diimpor, bahan kunci tidak dapat diambil kembali dari KMS. Simpan di lokasi aman sebelum melakukan impor.
Prasyarat
Sebelum memulai, pastikan Anda telah:
Memiliki instans KMS yang telah dibeli dan diaktifkan. Untuk informasi lebih lanjut, lihat Beli dan aktifkan instans KMS.
Impor bahan kunci di Konsol KMS
Alur impor berbasis konsol terdiri dari empat langkah:
Buat kunci asimetris dengan origin bahan kunci eksternal.
Unduh kunci publik pembungkus (wrapping public key) dan token impor.
Enkripsi kunci privat Anda menggunakan kunci publik pembungkus.
Unggah bahan kunci terenkripsi dan token impor.
Langkah 1: Buat kunci asimetris
Buat kunci asimetris yang menggunakan origin bahan kunci eksternal. Langkah-langkahnya sedikit berbeda tergantung pada tipe instans KMS Anda.
Kunci terproteksi perangkat lunak
Masuk ke Konsol KMS. Di bilah navigasi atas, pilih wilayah. Di panel navigasi kiri, pilih Resource > Keys.
Di tab Customer Master Keys, pilih instans manajemen kunci perangkat lunak dari daftar drop-down Instance ID lalu klik Create Key.
Di panel Create Key, konfigurasikan parameter berikut lalu klik OK.
Parameter Deskripsi Key type Pilih Asymmetric Key. Key specifications Pilih spesifikasi: RSA_2048, RSA_3072, EC_P256, atau EC_P256K. Key usage ENCRYPT/DECRYPT: mengenkripsi atau mendekripsi data. SIGN/VERIFY: menandatangani data atau memverifikasi tanda tangan digital. Key alias Alias untuk kunci. Karakter yang diizinkan: huruf, angka, garis bawah ( _), tanda hubung (-), dan garis miring maju (/).Tag key, Tag value Tag untuk mengklasifikasikan dan mengelola kunci. Panjang maksimum tag key atau value adalah 128 karakter (huruf, angka, /,\,_,-,.,+,=,:,@, spasi). Tag key tidak boleh diawali denganaliyunatauacs:. Maksimal 20 pasangan kunci-nilai tag per kunci.Description Deskripsi opsional untuk kunci. Policy settings (di bawah Advanced settings) Lihat Overview. Key material origin (di bawah Advanced settings) Pilih External (Import Key Material). Baca dan centang pernyataan: I understand the implications of using the external key materials.
Kunci terproteksi perangkat keras
Masuk ke Konsol KMS. Di bilah navigasi atas, pilih wilayah. Di panel navigasi kiri, pilih Resource > Keys.
Di tab Customer Master Keys, pilih instans manajemen kunci perangkat keras dari daftar drop-down Instance ID lalu klik Create Key.
Di panel Create Key, konfigurasikan parameter berikut lalu klik OK.
Parameter Deskripsi Key type Pilih Asymmetric Key. Key specifications Pilih spesifikasi: RSA_2048, RSA_3072, RSA_4096, EC_P256, atau EC_P256K. Key usage ENCRYPT/DECRYPT: mengenkripsi atau mendekripsi data. SIGN/VERIFY: menandatangani data atau memverifikasi tanda tangan digital. Key alias Alias untuk kunci. Karakter yang diizinkan: huruf, angka, garis bawah ( _), tanda hubung (-), dan garis miring maju (/).Tag key, Tag value Tag untuk mengklasifikasikan dan mengelola kunci. Panjang maksimum tag key atau value adalah 128 karakter (huruf, angka, /,\,_,-,.,+,=,:,@, spasi). Tag key tidak boleh diawali denganaliyunatauacs:. Maksimal 20 pasangan kunci-nilai tag per kunci.Description Deskripsi opsional untuk kunci. Policy settings (di bawah Advanced settings) Lihat Overview. Key material origin (di bawah Advanced settings) Pilih External (Import Key Material). Baca dan centang pernyataan: I understand the implications of using the external key materials.
Langkah 2: Unduh kunci publik pembungkus dan token impor
Untuk mengimpor bahan kunci, Anda memerlukan dua file dari KMS:
Wrapping public key — digunakan untuk mengenkripsi bahan kunci Anda sebelum diunggah.
Import token — mengotorisasi operasi impor.
Temukan kunci yang telah Anda buat lalu klik Details di kolom Actions. Di tab Key Material, klik Obtain Parameters for Import.
Di kotak dialog Obtain Parameters to Import Key Material, pilih Public Key Type dan Encryption Algorithm, lalu klik Next. Gunakan tabel berikut untuk menentukan jenis kunci publik pembungkus dan algoritma enkripsi yang tepat untuk kunci Anda.
Tipe bahan kunci Spesifikasi kunci Jenis kunci publik pembungkus Algoritma enkripsi Kunci privat RSA (terproteksi perangkat lunak) RSA_2048, RSA_3072 RSA_2048 RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD Kunci privat ECC (terproteksi perangkat lunak) EC_P256, EC_P256K RSA_2048 RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD Kunci privat RSA (terproteksi perangkat keras) RSA_2048, RSA_3072, RSA_4096 RSA_2048 RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD Kunci privat ECC (terproteksi perangkat keras) EC_P256, EC_P256K RSA_2048 RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD Unduh kedua file tersebut dan simpan di lokasi aman.
Kunci publik format DER: nama file dalam format
publickey_******.bin.Kunci publik format PEM: nama file dalam format
publickey_******.pem.Import token: nama file dalam format
token_******.txt.
Token impor berlaku selama 24 jam dan dapat digunakan ulang dalam periode tersebut. Setelah 24 jam, unduh token impor dan kunci publik pembungkus baru.
Selalu gunakan kunci publik pembungkus dan token impor dari unduhan yang sama. Jangan mencampur file dari unduhan berbeda.
Langkah 3: Enkripsi kunci privat
Anda harus mengenkripsi kunci privat sebelum mengunggahnya. Proses enkripsi menggunakan skema pembungkus ganda yang melibatkan tiga kunci.
| Kunci | Singkatan | Tipe | Penyedia | Deskripsi |
|---|---|---|---|---|
| Target asymmetric key | TAK | Pasangan kunci RSA atau ECC | Sistem Anda, KMI, atau HSM | Pasangan kunci yang ingin Anda gunakan. TAKpub adalah kunci publik; TAKpriv adalah kunci privat yang akan diimpor. |
| Import wrapping key | IWK | Pasangan kunci RSA | KMS | Pasangan kunci yang digunakan untuk mengamankan proses impor. IWKpub adalah kunci publik pembungkus yang telah Anda unduh. |
| Ephemeral symmetric key | ESK | AES-256 (atau SM4) | Sistem Anda | Kunci simetris sementara yang mengenkripsi TAKpriv. Hancurkan segera setelah digunakan. |
Persyaratan format untuk TAKpriv:
Encode kunci privat sesuai dengan tipenya (RSA: RFC 3447; ECC: RFC 5915), lalu ubah ke format PKCS #8 (RFC 5208). Output akhir harus dalam encoding DER.
Langkah-langkah enkripsi:
Siapkan TAKpriv dalam format PKCS #8 DER. Jika kunci privat Anda sudah dalam format ini, lewati langkah ini.
Hasilkan ESK AES-256 (32 byte acak).
Enkripsi ESK dengan IWKpub menggunakan RSAES-OAEP (SHA-256 untuk hash dan MGF1). Hasilnya adalah
Cipher(ESK).Enkripsi TAKpriv dengan ESK menggunakan mode AES-256 ECB dengan padding PKCS #7. Hasilnya adalah
Cipher(TAKpriv).Gabungkan dua ciphertext tersebut dalam urutan
Cipher(ESK) || Cipher(TAKpriv), lalu encode hasilnya dengan Base64. Inilah bahan kunci terenkripsi Anda.
Contoh: enkripsi kunci privat RSA_2048 dengan OpenSSL
# Langkah 1: Hasilkan kunci privat RSA_2048 untuk TAK dan ubah ke format PKCS #8 DER
openssl genrsa -out TakPrivPkcs1.pem 2048
openssl pkcs8 -topk8 -inform PEM -in TakPrivPkcs1.pem -outform der -nocrypt -out TakPrivPkcs8.bin
# Langkah 2: Hasilkan ESK AES-256 (32 byte)
openssl rand -out EskAes256.bin 32
# Langkah 3: Enkripsi ESK dengan kunci publik IWK menggunakan RSAES-OAEP (SHA-256)
# Ganti PublicKey.pem dengan file kunci publik pembungkus yang Anda unduh dari Konsol KMS.
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
# Langkah 4: Enkripsi TAKpriv dengan ESK menggunakan AES-256 ECB + padding PKCS #7
xxd -l 32 -c 32 -ps EskAes256.bin | xargs -I {} openssl enc -aes-256-ecb -e -K {} \
-in TakPrivPkcs8.bin -nosalt -out CipherTakPriv.bin
# Langkah 5: Gabungkan dan encode hasilnya dengan Base64
cat CipherEsk.bin CipherTakPriv.bin > EncryptedKeyMaterial.bin
openssl enc -e -base64 -A -in EncryptedKeyMaterial.bin -out EncryptedKeyMaterial_base64.txtFile EncryptedKeyMaterial_base64.txt berisi bahan kunci terenkripsi yang akan diunggah pada langkah berikutnya.
Langkah 4: Impor bahan kunci
Di halaman detail kunci, klik Import Key Material.
Di kotak dialog Import Wrapped Key Material, konfigurasikan parameter berikut lalu klik OK.
Parameter Deskripsi Wrapped key material Unggah file bahan kunci terenkripsi yang dihasilkan pada Langkah 3. Import token Unggah file token impor yang diunduh pada Langkah 2. Key material expired on Pilih Never Expire atau tentukan waktu kedaluwarsa. Jika Anda menetapkan waktu kedaluwarsa, KMS akan menghapus bahan kunci saat waktu tersebut tiba, dan kunci menjadi tidak tersedia hingga Anda mengimpor kembali bahan kunci yang sama.
Setelah impor, status kunci berubah dari Pending Import menjadi Enabling.
Impor bahan kunci menggunakan Alibaba Cloud SDK
Contoh Java berikut menunjukkan cara membuat kunci asimetris eksternal di KMS dan mengimpor bahan kunci menggunakan Alibaba Cloud SDK.RSA atau ECC
Kredensial dibaca dari variabel lingkungan. Simpan ID AccessKey dan AccessKey Secret Anda di ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET alih-alih hardcoding di proyek Anda.
Untuk konfigurasi kredensial, lihat Manage access credentials.
Untuk penyiapan variabel lingkungan, lihat Configure environment variables in Linux, macOS, and Windows.
Semua contoh menggunakan algoritma RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD atau SM2PKE_SM4_ECB untuk mengenkripsi kunci simetris sementara sebelum merakit muatan bahan kunci akhir.
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) {
// Inisialisasi Alibaba Cloud SDK.
DefaultAcsClient client = getClientForPublicEndpoint(regionId, accessKeyId, accessKeySecret);
BringYourOwnAsymmetricKeySample sample = new BringYourOwnAsymmetricKeySample(client);
// Buat dan impor kunci EC_SM2 eksternal.
sample.doByok("EC_SM2", "EC_SM2", sample.SM2PKE_SM4_ECB, "SM4");
// Buat dan impor kunci EC_P256 eksternal.
sample.doByok("EC_P256", "RSA_2048", sample.RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD, "AES_256");
// Buat dan impor kunci RSA eksternal.
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 {
// Buat kunci ECC eksternal.
CreateKeyResponse.KeyMetadata keyMetadata = this.createExternalKeyInDkms(dedicatedKmsInstanceId, targetKeySpec, "SIGN/VERIFY");
String keyId = keyMetadata.getKeyId();
// Peroleh parameter yang digunakan untuk mengimpor bahan kunci.
GetParametersForImportResponse parametersForImportResponse = this.getParametersForImport(keyId, wrappingKeySpec,
wrappingAlgorithm);
String importToken = parametersForImportResponse.getImportToken();
String publicKeyBase64 = parametersForImportResponse.getPublicKey();
// Buat ESK.
byte[] ephemeralSymmetricKeyPlaintext = this.generateEphemeralSymmetricKey(ephemeralKeySpec);
// Buat TAK.
byte[] targetAsymmetricKeyPlaintext = this.generateTargetAsymmetricKey(targetKeySpec);
// Gunakan kunci publik IWK untuk mengenkripsi ESK.
byte[] ephemeralSymmetricKeyCipher = this.encryptEphemeralSymmetricKey(publicKeyBase64,
wrappingAlgorithm, ephemeralSymmetricKeyPlaintext);
// Gunakan ESK untuk mengenkripsi TAK.
byte[] targetAsymmetricKeyCipher = this.encryptTargetAsymmetricKey(ephemeralSymmetricKeyPlaintext, targetAsymmetricKeyPlaintext,
wrappingAlgorithm);
// Rakit bahan kunci terenkripsi: 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);
// Impor bahan kunci.
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();
// Buat kunci eksternal.
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 {
// Jika ESK bertipe AES_256, atur panjang menjadi 32 bit.
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;
// Buat kunci SM2 dan peroleh nilai parameter D untuk kunci privat.
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;
}
// Hasilkan kunci privat RSA atau ECC.
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")) {
// Hasilkan kunci privat EC_P256K.
privateKey = generateEccKeyPair("secp256k1").getPrivate();
} else {
// Hasilkan kunci privat EC_P256.
privateKey= generateEccKeyPair("secp256r1").getPrivate();
}
}
if (privateKey != null) {
// Kembalikan kunci privat dalam format PKCS #8.
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;
}
}Ganti placeholder berikut:
| Placeholder | Deskripsi |
|---|---|
* Provide your DedicatedKmsInstanceId * | ID instans KMS khusus Anda |
cn-hangzhou | Wilayah tempat instans KMS Anda ditempatkan |
FAQ
Apakah saya bisa menghapus bahan kunci?
Ya. Setelah bahan kunci dihapus atau kedaluwarsa, kunci menjadi tidak tersedia hingga Anda mengimpor kembali bahan kunci yang sama.
Untuk menghapus bahan kunci secara langsung:
Konsol KMS: Di halaman detail kunci, klik tab Key Material lalu klik Delete Key Material.
API KMS: Panggil operasi DeleteKeyMaterial. Ini akan menghapus bahan kunci tetapi tidak menghapus kuncinya sendiri.
Untuk mengatur penghapusan otomatis, tentukan waktu kedaluwarsa saat melakukan impor. KMS akan menghapus bahan kunci saat waktu kedaluwarsa tercapai.
Bagaimana cara mengimpor kembali bahan kunci yang sama?
Jika bahan kunci telah kedaluwarsa atau dihapus, impor kembali bahan kunci yang sama untuk memulihkan kunci.
Di halaman detail kunci, klik tab Key Material lalu klik Delete Key Material untuk menghapus bahan kunci yang kedaluwarsa.
Unduh kunci publik pembungkus dan token impor baru (lihat Langkah 2). Prosedur pembungkus tidak memengaruhi konten bahan kunci, sehingga Anda dapat menggunakan kunci publik pembungkus dan algoritma yang berbeda.
Enkripsi bahan kunci menggunakan kunci publik pembungkus baru (lihat Langkah 3). Bahan kunci itu sendiri harus identik dengan yang asli.
Unggah bahan kunci terenkripsi dengan token impor baru (lihat Langkah 4).
Bagaimana cara memeriksa origin bahan kunci suatu kunci?
Konsol KMS: Di tab Customer Master Keys, temukan kunci tersebut lalu klik Details di kolom Actions. Periksa bidang Key Material Origin di halaman detail.
API KMS: Panggil DescribeKey. Jika bidang
OriginbernilaiEXTERNAL, berarti bahan kunci diimpor. Jika bernilaiAliyun_KMS, berarti KMS yang menghasilkan bahan kunci tersebut.
Apakah rotasi kunci berfungsi dengan bahan kunci yang diimpor?
Dukungan rotasi kunci bergantung pada tipe kunci:
Kunci simetris terproteksi perangkat lunak dengan bahan kunci yang diimpor: hanya mendukung rotasi manual segera. Rotasi periodik otomatis tidak didukung. Untuk detailnya, lihat Rotate a Bring-Your-Own-Key (BYOK) key.
Kunci asimetris terproteksi perangkat lunak dengan bahan kunci yang diimpor: rotasi tidak didukung.
Kunci terproteksi perangkat keras (simetris dan asimetris) dengan bahan kunci yang diimpor: rotasi tidak didukung.