Todos os produtos
Search
Central de documentação

Key Management Service:Importar material de chave para uma chave assimétrica

Última atualização: Sep 18, 2026

Ao criar uma chave assimétrica com origem de material de chave externa, o KMS não gera o material de chave. Você deve importar seu próprio material de chave. Este tópico descreve como importar material de chave para uma chave assimétrica.

Importante

Se sua instância de gerenciamento de chaves de software ou de hardware não suportar a importação de material de chave, ou se a importação falhar, entre em contato com o suporte técnico da Alibaba Cloud para atualizar sua instância.

Recursos

Em setores regulamentados, as auditorias de conformidade frequentemente exigem a comprovação da custódia exclusiva do material de chave criptográfica. Ao criar uma chave assimétrica com origem de material de chave externa, o Key Management Service (KMS) não gera o material de chave — você fornece e importa o seu próprio. Esse processo é conhecido como Bring Your Own Key (BYOK).

Tipo de gerenciamento de chaves

Importar material de chave assimétrica

Chave padrão

  • Chave mestra do cliente: Unsupported

  • Chave de service: Unsupported

Chave protegida por software

Supported

Chave protegida por hardware

Supported

Observações de uso

  • Após a primeira importação de material de chave, a chave fica vinculada a esse material e não aceita mais a importação de outros materiais de chave.

  • É possível importar o mesmo material de chave várias vezes para uma chave do KMS conforme necessário, mas não é permitido importar materiais de chave diferentes para uma única chave do KMS.

  • Caso o material de chave expire ou seja excluído, importe o mesmo material novamente para reativar a chave. O material de chave não pode ser exportado após a importação. Armazene-o adequadamente.

Escopo

Uma instância do KMS deve estar comprada e ativada. Para mais informações, consulte Purchase and enable a KMS instance.

Importar material de chave no console do KMS

Etapa 1: Criar uma chave assimétrica com origem de material de chave externa

Antes de importar o material de chave, crie uma chave assimétrica com origem de material de chave externa.

Chave protegida por software

  1. Faça login no console do Key Management Service. Na barra de navegação superior, selecione uma região. No painel de navegação à esquerda, escolha Resources > Keys.

  2. Na aba Customer Master Keys, selecione uma instância de gerenciamento de chaves de software na lista suspensa Instance ID e clique em Create Key.

  3. No painel Create Key, preencha as configurações dos parâmetros e clique em OK.

    Parâmetro

    Descrição

    Key Type

    Selecione Asymmetric Key.

    Key Specifications

    Especificações de chave assimétrica: RSA_2048, RSA_3072, RSA_4096, EC_P256 e EC_P256K.

    Key Usage

    A finalidade da chave. Valores válidos:

    • Encrypt/Decrypt: criptografa e descriptografa dados.

    • Sign/Verify: gera e verifica assinaturas digitais.

    Key Alias

    O alias da chave. São aceitos letras, dígitos, sublinhados (_), hifens (-) e barras (/).

    Tags

    As tags da chave, que permitem classificar as chaves. Cada tag consiste em um par chave-valor.

    Nota
    • Formato de uma chave de tag e de um valor de tag: Uma chave de tag ou um valor de tag pode ter até 128 caracteres e conter letras, dígitos, barras (/), barras invertidas (\), sublinhados (_), hifens (-), pontos (.), sinais de adição (+), sinais de igual (=), dois-pontos (:), arrobas (@) e espaços.

    • Uma chave de tag não pode começar com aliyun ou acs:.

    • Cada chave aceita até 20 pares chave-valor de tag.

    Description

    A descrição da chave.

    Advanced Settings

    • Policy Settings: Para mais informações, consulte Key policy overview.

    • Key Material Origin: Selecione External (Import Key Material).

      Nota

      Leia atentamente e selecione I understand the methods and implications of using external key material.

Chave protegida por hardware

  1. Faça login no console do Key Management Service. Na barra de navegação superior, selecione uma região. No painel de navegação à esquerda, escolha Resources > Keys.

  2. Na aba Customer Master Keys, selecione uma instância de gerenciamento de chaves de hardware na lista suspensa Instance ID e clique em Create Key.

  3. No painel Create Key, preencha as configurações dos parâmetros e clique em OK.

    Parâmetro

    Descrição

    Key Type

    Selecione Asymmetric Key.

    Key Specifications

    Especificações de chave assimétrica: RSA_2048, RSA_3072, RSA_4096, EC_P256 e EC_P256K

    Key Usage

    A finalidade da chave. Valores válidos:

    • Encrypt/Decrypt: criptografa e descriptografa dados.

    • Sign/Verify: gera e verifica assinaturas digitais.

    Key Alias

    O alias da chave. São aceitos letras, dígitos, sublinhados (_), hifens (-) e barras (/).

    Tags

    As tags da chave, que permitem classificar as chaves. Cada tag consiste em um par chave-valor.

    Nota
    • Formato de uma chave de tag e de um valor de tag: Uma chave de tag ou um valor de tag pode ter até 128 caracteres e conter letras, dígitos, barras (/), barras invertidas (\), sublinhados (_), hifens (-), pontos (.), sinais de adição (+), sinais de igual (=), dois-pontos (:), arrobas (@) e espaços.

    • Uma chave de tag não pode começar com aliyun ou acs:.

    • Cada chave aceita até 20 pares chave-valor de tag.

    Description

    A descrição da chave.

    Advanced Settings

    • Policy Settings: Para mais informações, consulte Key policy overview.

    • Key Material Origin: Selecione External (Import Key Material).

      Nota

      Leia atentamente e selecione I understand the methods and implications of using external key material.

Etapa 2: Baixar uma chave pública de encapsulamento e um token de importação

Os parâmetros para importar material de chave incluem uma chave pública de encapsulamento e um token de importação. A chave pública de encapsulamento serve para criptografar o material de chave e protegê-lo durante o processo de importação. O token de importação autoriza a operação.

  1. Localize a chave desejada e clique em Actions na coluna Details. Na página de detalhes da chave, na seção Key Material, clique em Obtain Parameters for Import.

  2. Na caixa de diálogo Obtain Parameters to Import Key Material, selecione o Public Key Type e o Encryption Algorithm e clique em Next.

    Tipo de gerenciamento de chaves

    Especificações da chave

    Tipo de chave pública de encapsulamento

    Algoritmo de criptografia

    Chave protegida por software

    • RSA_2048

    • RSA_3072

    • EC_P256

    • EC_P256K

    RSA_2048

    RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD

    Chave protegida por hardware

    • RSA_2048

    • RSA_3072

    • RSA_4096

    • EC_P256

    • EC_P256K

    RSA_2048

    RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD

  3. Baixe a chave pública de encapsulamento e o token de importação e armazene-os com segurança.

    • Public Key Format:

      • DER Format: O arquivo baixado recebe o nome WrappingPublicKey**.bin por padrão.

      • PEM Format: O arquivo baixado recebe o nome WrappingPublicKey**.pem por padrão.

    • Import Token: O arquivo baixado recebe o nome ImportToken***.txt por padrão.

      Importante
      • Um token de importação tem validade de 24 horas e pode ser reutilizado nesse período. Após o vencimento, obtenha um novo token de importação e uma nova chave pública.

      • A chave pública de encapsulamento e o token de importação devem ser usados em conjunto. Não é possível usar uma chave pública de encapsulamento de um download com um token de importação de outro.

Etapa 3: Criptografar o material de chave usando a chave pública de encapsulamento

Gere e criptografe o material de chave no seu ambiente de sistema. As chaves abaixo são utilizadas nesse processo. Consulte a tabela a seguir para obter detalhes.

Chave

Finalidade

Fornecedor

Observações

Chave Assimétrica de Destino (TAK)

A chave assimétrica de destino a ser importada.

Seu ambiente de sistema ou ferramenta (como uma infraestrutura de gerenciamento de chaves offline KMI ou um módulo de segurança de hardware offline HSM).

  • TAKpub: a parte da chave pública

  • TAKpriv: a parte da chave privada

Chave de Encapsulamento de Importação (IWK)

A chave de criptografia usada para importar a TAK.

Alibaba Cloud KMS.

  • IWKpub: a parte da chave pública

    Nota

    Esta é a chave pública de encapsulamento que você baixou do console do KMS.

  • IWKpriv: a parte da chave privada

Chave Simétrica Efêmera (ESK)

Uma chave simétrica transitória usada para criptografar diretamente a TAKpriv.

Seu sistema ou ferramenta no ambiente de origem. Destrua-a imediatamente após exportar a TAK.

N/A

  1. Crie uma chave privada assimétrica de destino (TAKpriv). A especificação da chave deve ser consistente com aquela selecionada ao criar a chave assimétrica. Se você já possui uma chave privada assimétrica de destino (TAKpriv), pule esta etapa.

    Nota

    O formato da TAKpriv deve seguir: chaves privadas RSA são codificadas conforme RFC 3447, chaves privadas ECC conforme RFC 5915 e depois encapsuladas no formato PKCS#8 conforme RFC 5208.

  2. Crie uma chave simétrica efêmera (ESK).

  3. Use a chave pública de encapsulamento de importação (IWKpub) para criptografar a chave simétrica efêmera (ESK) e obter o texto cifrado da chave simétrica efêmera (Cipher(ESK)).

  4. Utilize a chave simétrica efêmera (ESK) para criptografar a chave privada assimétrica de destino (TAKpriv) e obter o texto cifrado da chave privada (Cipher(TAKpriv)).

  5. Monte os dados resultantes no formato Cipher(ESK)||Cipher(TAKpriv) para obter o material de chave criptografado.

Exemplo: Usar OpenSSL para gerar material de chave para o algoritmo RSA_2048

  1. Crie uma chave privada assimétrica de destino para o algoritmo RSA_2048 e converta-a para o formato PKCS#8.

    openssl genrsa -out TakPrivPkcs1.pem 2048
    openssl pkcs8 -topk8 -inform PEM -in TakPrivPkcs1.pem -outform der -nocrypt -out TakPrivPkcs8.bin
  2. Crie uma chave simétrica efêmera (ESK) para o algoritmo AES_256.

    openssl rand -out EskAes256.bin 32
  3. Use a chave pública de encapsulamento de importação (IWKpub) para criptografar a chave simétrica efêmera (ESK) e obter o texto cifrado da chave simétrica efêmera (Cipher(ESK)). É utilizada a criptografia padrão RSAES OAEP, onde MGF1 e o algoritmo de hash são SHA256.

    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
    Nota

    Substitua PublicKey.pem pelo nome do arquivo de chave pública baixado do console do KMS.

  4. Utilize a chave simétrica efêmera (ESK) para criptografar a chave privada assimétrica de destino (TAKpriv) e gerar o texto cifrado da chave privada (Cipher(TAKpriv)). O modo de criptografia é ECB e o modo de preenchimento é 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
  5. Monte os dados resultantes no formato Cipher(ESK) || Cipher(TAKpriv) e execute a codificação Base64.

    cat CipherEsk.bin CipherTakPriv.bin > EncryptedKeyMaterial.bin
    openssl enc -e -base64 -A -in EncryptedKeyMaterial.bin -out EncryptedKeyMaterial_base64.txt
    Nota

    EncryptedKeyMaterial_base64.txt é o arquivo de material de chave que pode ser importado para o KMS.

Etapa 4: Importar material de chave

Na página de detalhes da chave, clique em Import Key Material. Na caixa de diálogo Import Wrapped Key Material, conclua as configurações e clique em OK.

Parâmetro

Descrição

Wrapped Key Material

Faça upload do arquivo de material de chave gerado em Step 3: Encrypt the key material using the wrapping public key.

Import Token

Faça upload do arquivo de token baixado em Step 2: Download a wrapping public key and an import token.

Key Material Expired On

Selecione Never Expire ou especifique um tempo de expiração personalizado.

Importante

Se você definir um tempo de expiração para o material de chave, o KMS excluirá o material expirado após esse prazo e você não poderá mais usá-lo. Para restaurá-lo, importe o mesmo material de chave novamente.

Após a importação bem-sucedida do material de chave, o status da chave muda de Pending Import para Enabling.

Importar material de chave usando o Alibaba Cloud SDK

Use o Alibaba Cloud SDK para criar chaves RSA e ECC no KMS e importar material de chave. O exemplo de código Java a seguir demonstra o processo.

Nota

Um par de AccessKey de uma conta Alibaba Cloud tem permissões para todas as operações de API. Recomendamos usar um usuário RAM para chamar operações de API ou executar O&M de rotina. Para evitar riscos de segurança, não codifique rigidamente seu AccessKey ID e AccessKey Secret no código do projeto. Codificar credenciais pode levar a vazamentos que comprometem todos os recursos da sua conta.

Este tópico fornece um exemplo de como configurar as variáveis de ambiente ALIBABA_CLOUD_ACCESS_KEY_ID e ALIBABA_CLOUD_ACCESS_KEY_SECRET para autenticação de identidade.

Instalar o SDK

Adicione a dependência Maven ao seu projeto para baixar automaticamente o pacote de instalação Java do repositório Maven. Use o Alibaba Cloud SDK V2.0.

 <dependency>
 <groupId>com.aliyun</groupId>
 <artifactId>kms20160120</artifactId>
 <version>1.4.0</version>
 </dependency>
 <dependency>
 <groupId>com.aliyun</groupId>
 <artifactId>tea</artifactId>
 <version>1.3.2</version>
 </dependency>
package com.aliyun;

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.aliyun.kms20160120.models.*;
import com.aliyun.kms20160120.Client;
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 {
    private final static String dedicatedKmsInstanceId = "<yourKmsInstanceId>";
    // The public endpoint of KMS.
    private final static String endpoint = "kms.<regionId>.aliyuncs.com";
    private final Client 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) throws Exception {
        // Initialize the KMS SDK.
        Client client = BringYourOwnAsymmetricKeySample.createClient();
        BringYourOwnAsymmetricKeySample sample = new BringYourOwnAsymmetricKeySample(client);

        // Create and import an external key of the EC_SM2 type.
        sample.doByok("EC_SM2", "EC_SM2", sample.SM2PKE_SM4_ECB, "SM4");
        // Create and import an external key of the EC_P256 type.
        sample.doByok("EC_P256", "RSA_2048", sample.RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD, "AES_256");
        // Create and import an external key of the RSA type.
        sample.doByok("RSA_2048", "RSA_2048", sample.RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD, "AES_256");
    }

    /**
     * <b>description</b> :
     * <p>Initialize the client using credentials.</p>
     *
     * @return Client
     * @throws Exception
     */
    public static Client createClient() throws Exception {
        // We recommend that you use the more secure credential-based initialization without hardcoding AccessKey pairs. For more information, see: https://www.alibabacloud.com/help/document_detail/378657.html.
        com.aliyun.credentials.Client credential = new com.aliyun.credentials.Client();
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                .setCredential(credential);
        // For the endpoint, see https://api.alibabacloud.com/product/Kms.
        config.endpoint = endpoint;
        return new Client(config);
    }

    public BringYourOwnAsymmetricKeySample(Client kmsClient) {
        this.kmsClient = kmsClient;
    }

    public void doByok(String targetKeySpec, String wrappingKeySpec, String wrappingAlgorithm, String ephemeralKeySpec) {
        try {
            // Create an external ECC key.
            CreateKeyResponseBody.CreateKeyResponseBodyKeyMetadata keyMetadata = this.createExternalKeyInDkms(dedicatedKmsInstanceId, targetKeySpec, "SIGN/VERIFY");
            String keyId = keyMetadata.getKeyId();
            // Obtain the parameters for importing key material.
            GetParametersForImportResponse parametersForImportResponse = this.getParametersForImport(keyId, wrappingKeySpec,
                    wrappingAlgorithm);
            String importToken = parametersForImportResponse.body.getImportToken();
            String publicKeyBase64 = parametersForImportResponse.body.getPublicKey();
            // Generate the ephemeral symmetric key.
            byte[] ephemeralSymmetricKeyPlaintext = this.generateEphemeralSymmetricKey(ephemeralKeySpec);
            // Generate the target asymmetric key.
            byte[] targetAsymmetricKeyPlaintext = this.generateTargetAsymmetricKey(targetKeySpec);
            // Use the import wrapping key public key to encrypt the ephemeral symmetric key.
            byte[] ephemeralSymmetricKeyCipher = this.encryptEphemeralSymmetricKey(publicKeyBase64,
                    wrappingAlgorithm, ephemeralSymmetricKeyPlaintext);
            // Use the ephemeral symmetric key to encrypt the target asymmetric key.
            byte[] targetAsymmetricKeyCipher = this.encryptTargetAsymmetricKey(ephemeralSymmetricKeyPlaintext, targetAsymmetricKeyPlaintext,
                    wrappingAlgorithm);
            // Generate the key material.
            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 to KMS.
            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.setKeyId(keyId);
        request.setWrappingKeySpec(keySpec);
        request.setWrappingAlgorithm(algorithm);
        return this.kmsClient.getParametersForImport(request);
    }

    private CreateKeyResponseBody.CreateKeyResponseBodyKeyMetadata createExternalKeyInDkms(String dedicatedKmsInstance, String keySpec, String keyUsage) throws Exception {
        CreateKeyRequest request = new CreateKeyRequest();
        // Create an external key.
        request.setOrigin("EXTERNAL");
        request.setDKMSInstanceId(dedicatedKmsInstance);
        request.setKeySpec(keySpec);
        request.setKeyUsage(keyUsage);
        return kmsClient.createKey(request).body.keyMetadata;
    }

    private byte[] generateEphemeralSymmetricKey(String ephemeralSymmetricKeySpec) throws Exception {
        // If the ephemeral symmetric key is AES_256, the length is 32 bytes.
        int ephemeralSymmetricKeyLength = 32;
        if ("SM4".equals(ephemeralSymmetricKeySpec)) {
            ephemeralSymmetricKeyLength = 16;
        }
        byte[] key = new byte[ephemeralSymmetricKeyLength];
        new Random().nextBytes(key);
        return key;
    }

    private byte[] generateTargetAsymmetricKey(String keySpec) throws Exception {
        PrivateKey privateKey = null;
        // Generate an SM2 key and obtain the D value of 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 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 void importKeyMaterial(
            String keyId,
            String material,
            String token,
            Long expire
    ) throws Exception {
        ImportKeyMaterialRequest req = newImportKeyMaterialRequest(
                keyId, material, token, expire);
        this.kmsClient.importKeyMaterial(req);
    }

    private ImportKeyMaterialRequest newImportKeyMaterialRequest(
            String keyId,
            String material,
            String token,
            Long expire
    ) {
        ImportKeyMaterialRequest request = new ImportKeyMaterialRequest();
        request.setEncryptedKeyMaterial(material);
        request.setImportToken(token);
        request.setKeyId(keyId);
        request.setKeyMaterialExpireUnix(expire);
        return request;
    }
}
            

Perguntas frequentes

  • A exclusão de material de chave é suportada?

    Sim, é suportada.

    Importante

    Depois que o material de chave importado expira ou é excluído, a chave fica indisponível. Importe o mesmo material de chave novamente para restaurar a chave.

    • Excluir material de chave diretamente

      • Console: Na página de detalhes da chave, na seção Key Material, clique em Delete Key Material.

      • API: Chame a operação DeleteKeyMaterial para excluir o material de chave. Esta operação não exclui sua chave.

    • Exclusão automática pelo KMS após expiração

      Defina um tempo de expiração ao importar o material de chave. Após esse prazo, o KMS exclui o material de chave expirado.

  • Como reimportar o mesmo material de chave?

    Após a expiração ou exclusão do material de chave, importe o mesmo material novamente para que a chave continue utilizável.

    1. Exclua o material de chave expirado.

      Na página de detalhes da chave, clique na aba Key Material e clique em Delete Key Material.

    2. Baixe novamente a chave pública de encapsulamento e o token de importação. Para mais informações, consulte Step 2: Download a wrapping public key and an import token.

      Nota

      O processo de encapsulamento de chave não afeta o conteúdo do material de chave. Use uma chave pública de encapsulamento e um algoritmo de encapsulamento diferentes para importar o mesmo material de chave.

    3. Criptografe o material de chave usando a chave pública de encapsulamento. Para mais informações, consulte Step 3: Encrypt the key material using the wrapping public key.

      Nota

      O material de chave deve ser o mesmo que expirou anteriormente.

    4. Use o token de importação para importar o material de chave criptografado. Para mais informações, consulte Step 4: Import key material.

  • Como determinar se o material de chave foi importado externamente ou gerado pelo KMS?

    • Método 1: Verificar no console do KMS.

      Na página Keys, clique na aba Customer Master Keys, selecione um Instance ID, localize a chave desejada, clique em Actions na coluna Details e verifique a Key Material Origin na página de detalhes.

    • Método 2: Verificar chamando a operação DescribeKey.

      Se o valor de Origin for EXTERNAL, o material de chave foi importado externamente. Se o valor de Origin for Aliyun_KMS, o material de chave foi gerado pelo KMS.

  • Como fazer a rotação de uma chave que usa material de chave externo?

    • Para uma chave simétrica protegida por software com material de chave externo importado, apenas a rotação manual imediata é suportada. A rotação periódica automática não é suportada. Para mais informações, consulte Bring Your Own Keys (BYOKs) with imported key material..

    • Para uma chave assimétrica protegida por software com material de chave externo importado, a rotação não é suportada.

    • Para uma chave protegida por hardware (simétrica ou assimétrica) com material de chave externo importado, a rotação não é suportada.

Referências