Saat membuat kunci asimetris dengan sumber bahan kunci eksternal, Key Management Service (KMS) tidak menghasilkan bahan kuncinya. Sebagai gantinya, Anda harus mengimpor bahan kunci milik Anda sendiri. Topik ini menjelaskan cara mengimpor bahan kunci ke dalam kunci asimetris.
Jika instans manajemen kunci perangkat lunak atau instans manajemen kunci perangkat keras Anda tidak mendukung pengimporan bahan kunci, atau jika terjadi kesalahan saat mengimpor bahan kunci, hubungi dukungan teknis Alibaba Cloud untuk meningkatkan instans tersebut.
Pengantar
Kunci merupakan sumber daya dasar di KMS. Sebuah kunci terdiri dari ID kunci, metadata dasar seperti status kunci, dan bahan kunci. Saat membuat kunci, Anda dapat memilih agar KMS menghasilkan bahan kuncinya atau menggunakan bahan kunci dari sumber eksternal. Jika Anda memilih sumber eksternal, Anda harus mengimpor bahan kunci eksternal tersebut ke dalam kunci. Fitur ini sering disebut Bring Your Own Key (BYOK).
Tabel berikut menjelaskan jenis manajemen kunci KMS yang mendukung pengimporan bahan kunci. Untuk informasi selengkapnya tentang jenis manajemen kunci, lihat Jenis manajemen kunci dan spesifikasi kunci.
: Menunjukkan bahwa pengimporan bahan kunci yang sesuai didukung.
: Menunjukkan bahwa pengimporan bahan kunci yang sesuai tidak didukung.
Jenis manajemen kunci | Impor bahan kunci simetris | Impor bahan kunci asimetris |
Kunci default |
|
|
Kunci yang dilindungi perangkat lunak | √ | √ |
Kunci yang dilindungi perangkat keras | √ | × |
Catatan penggunaan
Saat pertama kali 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 tersebut.
Anda dapat mengimpor ulang bahan kunci yang sama ke dalam kunci KMS sesuai kebutuhan, tetapi tidak dapat mengimpor bahan kunci yang berbeda.
Jika bahan kunci kedaluwarsa atau dihapus, Anda dapat mengimpor ulang bahan kunci yang sama agar kunci tersebut tersedia kembali. Setelah diimpor, bahan kunci tidak dapat diekspor. Simpan bahan kunci Anda di lokasi yang aman.
Prasyarat
Anda telah membeli dan mengaktifkan instans KMS. Untuk informasi selengkapnya, lihat Beli dan aktifkan instans KMS.
Impor bahan kunci di konsol KMS
Langkah 1: Buat kunci asimetris
Sebelum mengimpor bahan kunci, Anda harus membuat kunci asimetris dengan sumber bahan kunci eksternal.
Kunci yang dilindungi perangkat lunak
Masuk ke Konsol KMS. Di bilah navigasi atas, pilih wilayah. Di panel navigasi sebelah kiri, pilih .
Di tab Customer Master Keys, pilih instans KMS yang dikelola perangkat lunak dari daftar drop-down Instance ID, lalu klik Create Key.
Di panel Create Key, atur item konfigurasi, lalu klik OK.
Item konfigurasi
Deskripsi
Key Type
Jenis kunci. Pilih Asymmetric Key.
Key Specifications
Key Usage
Tujuan kunci. Nilai yang valid:
Encrypt/Decrypt: Enkripsi dan dekripsi data.
Sign/Verify: Pembuatan dan verifikasi tanda tangan digital.
Key Alias
Alias kunci. Alias dapat berisi huruf, angka, garis bawah (_), tanda hubung (-), dan garis miring (/).
Tag
Tag yang akan ditambahkan ke kunci. Gunakan tag untuk mengklasifikasikan dan mengelola kunci. Setiap tag adalah pasangan kunci-nilai yang terdiri dari kunci tag dan nilai tag.
CatatanKunci tag atau nilai tag dapat memiliki panjang hingga 128 karakter dan dapat berisi huruf, angka, garis miring (/), garis miring terbalik (\), garis bawah (_), tanda hubung (-), titik (.), tanda tambah (+), tanda sama dengan (=), titik dua (:), tanda @, dan spasi.
Kunci tag tidak boleh dimulai dengan
aliyunatauacs:.Anda dapat mengonfigurasi hingga 20 pasangan kunci-nilai untuk setiap kunci.
Description
Deskripsi kunci.
Advanced Settings
Policy Settings: Untuk informasi selengkapnya, lihat Ikhtisar kebijakan kunci.
Key Material Origin: Pilih External (Import Key Material).
CatatanBaca dan pilih Saya memahami implikasi dari penggunaan bahan kunci eksternal.
Kunci yang dilindungi perangkat keras
Masuk ke Konsol KMS. Di bilah navigasi atas, pilih wilayah. Di panel navigasi sebelah kiri, pilih .
Di tab Customer Master Keys, pilih instans manajemen kunci perangkat keras untuk Instance ID, lalu klik Create Key.
Di panel Create Key, konfigurasi parameter, lalu klik OK.
Item konfigurasi
Deskripsi
Key Type
Pilih Asymmetric Key.
Key Specifications
Key Usage
Tujuan kunci. Nilai yang valid:
Encrypt/Decrypt: Enkripsi dan dekripsi data.
Sign/Verify: Pembuatan dan verifikasi tanda tangan digital.
Key Alias
Alias kunci. Alias dapat berisi huruf, angka, garis bawah (_), tanda hubung (-), dan garis miring (/).
Tag
Tag yang akan ditambahkan ke kunci. Anda dapat menggunakan tag untuk mengklasifikasikan dan mengelola kunci. Setiap tag adalah pasangan kunci-nilai yang terdiri dari kunci tag dan nilai tag.
CatatanKunci tag atau nilai tag dapat memiliki panjang hingga 128 karakter dan dapat berisi huruf, angka, garis miring (/), garis miring terbalik (\), garis bawah (_), tanda hubung (-), titik (.), tanda tambah (+), tanda sama dengan (=), titik dua (:), tanda @, dan spasi.
Kunci tag tidak boleh dimulai dengan
aliyunatauacs:.Anda dapat mengonfigurasi hingga 20 pasangan kunci-nilai untuk setiap kunci.
Description
Deskripsi kunci.
Advanced Settings
Policy Settings: Untuk informasi selengkapnya, lihat Ikhtisar kebijakan kunci.
Key Material Origin: Pilih External (Import Key Material).
CatatanBaca dan pilih I understand the implications of using external key material.
Langkah 2: Unduh kunci publik pembungkus dan token impor
Parameter untuk mengimpor bahan kunci mencakup kunci publik pembungkus dan token impor. Kunci publik pembungkus digunakan untuk mengenkripsi bahan kunci guna melindunginya selama proses impor, sedangkan token impor diperlukan saat mengimpor bahan kunci.
Temukan kunci target, lalu klik Details di kolom Actions. Di halaman detail kunci, pada bagian 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.
Jenis manajemen kunci
Spesifikasi kunci
Jenis kunci publik pembungkus
Algoritma enkripsi
Kunci yang dilindungi perangkat lunak
RSA_2048
RSA_3072
EC_P256
EC_P256K
RSA_2048
RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD
Kunci yang dilindungi perangkat keras
RSA_2048
RSA_3072
RSA_4096
EC_P256
EC_P256K
RSA_2048
RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD
RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD: Untuk informasi selengkapnya tentang proses enkripsi, lihat Contoh: Gunakan OpenSSL untuk menghasilkan bahan kunci untuk algoritma RSA_2048.
Unduh kunci publik pembungkus dan token impor, lalu simpan di lokasi yang aman.
Public Key Format:
DER Format: Nama file yang diunduh secara default adalah publickey_******.bin.
PEM Format: File yang diunduh secara default bernama publickey_******.pem.
Import Token: File yang diunduh secara default bernama token_******.txt.
PentingToken impor berlaku selama 24 jam dan dapat digunakan beberapa kali dalam periode validitas tersebut. Setelah kedaluwarsa, Anda harus mendapatkan token impor dan kunci publik baru.
Kunci publik pembungkus dan token impor harus digunakan bersama-sama. Anda tidak dapat menggunakan kunci publik pembungkus dengan token impor dari unduhan yang berbeda.
Langkah 3: Gunakan kunci publik pembungkus untuk mengenkripsi bahan kunci
Hasilkan dan enkripsi bahan kunci di lingkungan sistem Anda. Tabel berikut menjelaskan kunci-kunci yang digunakan dalam proses tersebut.
Kunci | Tujuan | Penyedia | Deskripsi |
Kunci asimetris target (TAK) | Kunci asimetris target untuk diimpor. | Lingkungan sistem atau alat Anda seperti infrastruktur manajemen kunci (KMI) lokal atau modul keamanan perangkat keras (HSM). |
|
Kunci pembungkus impor (IWK) | Kunci enkripsi yang digunakan untuk mengimpor TAK. | Alibaba Cloud KMS. |
|
Kunci simetris sementara (ESK) | Kunci simetris sementara yang langsung mengenkripsi TAKpriv. | Hancurkan sistem atau alat di lingkungan sumber segera setelah Anda mengekspor TAK. | N/A |
Buat kunci privat asimetris target (TAKpriv). Spesifikasi kunci harus sama dengan yang Anda pilih saat membuat kunci asimetris. Jika Anda sudah memiliki TAKpriv, lewati langkah ini.
CatatanFormat TAKpriv harus mematuhi standar berikut: Kunci privat RSA dikodekan berdasarkan RFC 3447. Kunci privat ECC dikodekan berdasarkan RFC 5915. Kemudian, kunci tersebut dibungkus ke dalam format PKCS#8 berdasarkan RFC 5208.
Buat ESK.
Gunakan kunci publik pembungkus impor (IWKpub) untuk mengenkripsi ESK. Ini menghasilkan ciphertext ESK (Cipher(ESK)).
Gunakan ESK untuk mengenkripsi TAKpriv. Ini menghasilkan ciphertext kunci privat asimetris target (Cipher(TAKpriv)).
Rakit hasilnya dalam format Cipher(ESK)||Cipher(TAKpriv) untuk mendapatkan bahan kunci terenkripsi.
Langkah 4: Impor bahan kunci
Di halaman detail kunci, klik Import Key Material. Di kotak dialog Import Wrapped Key Material yang muncul, konfigurasi parameter, lalu klik OK.
Item konfigurasi | Deskripsi |
Wrapped Key Material | Unggah file bahan kunci yang dihasilkan di Langkah 3: Gunakan kunci publik pembungkus untuk mengenkripsi bahan kunci. |
Import Token | Unggah file token impor yang diunduh di Langkah 2: Unduh kunci publik pembungkus dan token impor. |
Key Material Expired On | Anda dapat memilih Never Expire atau menentukan waktu kedaluwarsa. Penting Jika Anda menentukan waktu kedaluwarsa untuk bahan kunci, KMS akan menghapus bahan kunci tersebut saat waktu kedaluwarsa tercapai, dan Anda tidak dapat lagi menggunakan bahan kunci tersebut. Jika ingin menggunakan kembali bahan kunci tersebut, Anda dapat mengimpor ulang bahan kunci yang sama ke dalam kunci. |
Setelah bahan kunci diimpor, status kunci berubah dari Pending Import menjadi Enabling.
Impor bahan kunci menggunakan SDK
Anda dapat menggunakan SDK Alibaba Cloud untuk membuat kunci algoritma RSA dan ECC di KMS dan mengimpor bahan kunci. Berikut adalah contoh kode Java:
Pasangan AccessKey Akun Alibaba Cloud memiliki izin atas semua operasi API. Menggunakan pasangan AccessKey untuk melakukan operasi merupakan operasi berisiko tinggi. Selain itu, gunakan Pengguna RAM untuk memanggil operasi API atau melakukan O&M rutin. Kami menyarankan agar Anda tidak menyimpan ID AccessKey dan Rahasia AccessKey di kode proyek Anda. Jika Anda melakukannya, pasangan AccessKey mungkin bocor dan keamanan semua sumber daya yang dimiliki akun Anda mungkin terganggu.
Dalam contoh ini, pasangan AccessKey disimpan dalam variabel lingkungan ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET untuk melakukan otentikasi identitas.
Untuk informasi selengkapnya tentang cara mengonfigurasi informasi autentikasi, lihat Kelola kredensial akses.
Metode untuk mengonfigurasi variabel lingkungan berbeda-beda tergantung sistem operasinya. Untuk informasi selengkapnya, lihat Konfigurasi variabel lingkungan di Linux, macOS, dan Windows.
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 SDK KMS.
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) {
/**
* Konstruksi Klien Aliyun:
* Atur RegionId, AccessKeyId, dan 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();
// Dapatkan 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);
// Hasilkan bahan kunci.
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();
//perlu 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 dapatkan 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;
}
}
FAQ
Apakah saya dapat menghapus bahan kunci?
Ya, Anda bisa.
Setelah bahan kunci yang diimpor kedaluwarsa atau dihapus, kunci yang menggunakan bahan kunci tersebut menjadi tidak tersedia. Untuk menggunakan kembali kunci tersebut, Anda harus mengimpor ulang bahan kunci yang sama.
Hapus bahan kunci secara langsung
Di konsol, pada halaman detail kunci, di area Key Material, klik Delete Key Material.
Operasi API: Panggil operasi DeleteKeyMaterial untuk menghapus bahan kunci. Operasi ini tidak menghapus kunci Anda.
Biarkan KMS menghapus bahan kunci setelah kedaluwarsa
Saat mengimpor bahan kunci, Anda dapat mengatur waktu kedaluwarsa. KMS akan menghapus bahan kunci setelah waktu yang ditentukan.
Bagaimana cara mengimpor ulang bahan kunci yang sama?
Setelah bahan kunci kedaluwarsa atau dihapus, Anda dapat mengimpor ulang bahan kunci yang sama untuk terus menggunakan kunci tersebut.
Hapus bahan kunci yang kedaluwarsa.
Di halaman detail kunci, klik tab Key Material, lalu klik Delete Key Material.
Unduh ulang kunci publik pembungkus dan token impor. Untuk informasi selengkapnya, lihat Langkah 2: Unduh kunci publik pembungkus dan token impor.
CatatanProses pembungkusan kunci tidak memengaruhi konten bahan kunci. Anda dapat menggunakan kunci publik pembungkus dan algoritma pembungkus yang berbeda untuk mengimpor bahan kunci yang sama.
Gunakan kunci publik pembungkus untuk mengenkripsi bahan kunci. Untuk informasi selengkapnya, lihat Langkah 3: Gunakan kunci publik pembungkus untuk mengenkripsi bahan kunci.
CatatanBahan kunci harus sama dengan bahan kunci yang kedaluwarsa.
Impor bahan kunci terenkripsi menggunakan token impor. Untuk informasi selengkapnya, lihat Langkah 4: Impor bahan kunci.
Bagaimana cara menentukan apakah bahan kunci diimpor atau dihasilkan oleh KMS?
Metode 1: Periksa konsol KMS.
Di halaman Keys, klik tab Customer Master Keys, pilih Instance ID, temukan kunci target, lalu klik Details di kolom Actions. Di halaman detail, Anda dapat melihat Key Material Source.
Metode 2: Panggil operasi DescribeKey.
Jika nilai
OriginadalahEXTERNAL, bahan kunci diimpor. Jika nilaiOriginadalahAliyun_KMS, bahan kunci dihasilkan oleh KMS.
Bagaimana cara memutar kunci yang menggunakan bahan kunci eksternal?
Untuk kunci simetris yang dilindungi perangkat lunak yang menggunakan bahan kunci yang diimpor, hanya rotasi manual segera yang didukung, bukan rotasi periodik otomatis. Untuk informasi selengkapnya, lihat Putar kunci Bring-Your-Own-Key (BYOK).
Rotasi tidak didukung untuk kunci asimetris yang dilindungi perangkat lunak yang menggunakan bahan kunci yang diimpor.
Rotasi tidak didukung untuk kunci yang dilindungi perangkat keras (baik simetris maupun asimetris) yang menggunakan bahan kunci yang diimpor.