Para ativos implantados na Alibaba Cloud ou em outros ambientes cloud com endereços IP públicos atribuídos, é necessário armazenar e transmitir dados sensíveis de forma segura para reduzir riscos de violação e atender a requisitos de conformidade. Para pequenos volumes de dados sensíveis, utilize o Key Management service (KMS) para criptografia e descriptografia online. Este tópico descreve os cenários, pré-requisitos e procedimentos para criptografia e descriptografia online.
Escopo
O tamanho dos dados para criptografia ou descriptografia simétrica não pode exceder 6 KB por operação.
O tamanho dos dados para criptografia ou descriptografia assimétrica não pode exceder 1 KB por operação.
Um tamanho de dados maior em uma única operação de criptografia aumenta a probabilidade de falhas na transmissão de rede e prolonga o tempo de transmissão. O tempo necessário para a instância do KMS criptografar e descriptografar os dados também aumenta.
Segurança das chaves
Não armazene chaves de criptografia em código frontend. O código JavaScript frontend é entregue integralmente ao navegador do usuário, e os valores das chaves podem ser visualizados e extraídos por meio das ferramentas de desenvolvedor do navegador. Seja uma chave simétrica, a chave privada de uma chave assimétrica ou um AccessKey usado para acessar o KMS, uma vez incorporado no código frontend, considera-se comprometido. Após o vazamento de uma chave, invasores podem descriptografar todo o histórico de textos cifrados, tornando a proteção por criptografia ineficaz.
A abordagem recomendada é manter todo o material de chaves no backend e centralizar as operações de criptografia e descriptografia nele:
O frontend transmite dados sensíveis ao servidor backend via HTTPS, onde o TLS garante a confidencialidade durante a transmissão.
O servidor backend chama a operação
EncryptouAsymmetricEncryptdo KMS para criptografar os dados e armazena o texto cifrado em bancos de dados ou outros meios de armazenamento.Quando o texto simples é necessário, o backend chama a operação
DecryptouAsymmetricDecryptpara descriptografar os dados e retorna o resultado ao frontend conforme necessário.
Com essa arquitetura, o material de chaves permanece hospedado na instância do KMS e nunca ultrapassa os limites do KMS. O backend mantém apenas as credenciais de acesso ao KMS, e o frontend jamais tem contato com as chaves.
Preparação
Antes de começar a chamar APIs para criptografia e descriptografia, conclua a preparação a seguir.
Etapa 1: Adquirir e ative uma instância do KMS
Adquira e ative uma instância do KMS (instância de gerenciamento de chaves por software ou por hardware) de acordo com seus requisitos de negócio e conformidade. Para mais informações, consulte Purchase and enable a KMS instance.
Etapa 2: crie uma chave
crie uma chave na instância do KMS ativada, de acordo com o seu cenário de criptografia.
Chave simétrica: usada para criptografia e descriptografia em um ambiente confiável.
Chave assimétrica: usada em cenários que cruzam fronteiras de confiança — por exemplo, o cliente usa uma chave pública para criptografar e o servidor usa uma chave privada para descriptografar.
Para mais informações, consulte Create a key.
Etapa 3: Preparar credenciais de acesso e permissões
Este tópico utiliza AccessKey como exemplo. Para mais informações sobre credenciais de acesso, consulte Create access credentials.
Por padrão, uma conta Alibaba Cloud possui permissões de administrador para todos os recursos, e essas permissões não podem ser modificadas. Para garantir a segurança dos recursos, recomendamos usar um usuário RAM para criar um par de AccessKey e conceder a ele apenas as permissões necessárias.
Faça login no console do RAM. Na página Users, clique em o nome do usuário RAM desejado.
Na aba Secret Management, na seção AccessKey, clique em Create AccessKey.
-
Conceda ao usuário RAM permissões para acessar o KMS.
-
Método 1: configure uma política baseada em identidade
Na coluna Actions do usuário RAM, clique em Grant Permission para anexar uma política de permissão de sistema integrada do KMS ao usuário RAM. Para mais informações sobre as políticas de permissão de sistema do KMS, consulte System policies for KMS.
NotaTambém é possível criar políticas de permissão personalizadas. Para mais informações, consulte Create a custom policy.
-
Método 2: configure uma política baseada em recurso
O KMS oferece suporte a políticas baseadas em recurso que concedem permissões de acesso a chaves e segredos individuais. Essas políticas permitem controlar quais contas Alibaba Cloud, usuários RAM e funções RAM podem gerencie ou usar chaves e segredos do KMS. Para mais informações, consulte Key policies e Secret policies.
-
Etapa 4: Obter informações de conexão e certificado CA
Ao chamar APIs, selecione o endpoint de gateway apropriado com base no seu ambiente de rede.
Este tópico utiliza o gateway dedicado por padrão.
|
Recurso |
Gateway compartilhado |
Gateway dedicado |
|
Endpoint |
|
|
|
Certificado CA |
Não necessário. |
Obrigatório. |
|
Cenário aplicável |
Acesso público, desenvolvimento e testes. |
Acesso interno via vpc, ambientes de produção, maior desempenho e isolamento. |
|
Como obter |
Para mais informações, consulte Alibaba Cloud SDK. |
Na página de detalhes da instância, baixe o certificado CA da instância e obtenha o endpoint vpc da instância. |
Cenários de aplicação
Cenário 1: Aplicações implantadas na Alibaba Cloud
Aplicações implantadas na Alibaba Cloud geram ou recebem dados sensíveis em texto simples. Esses dados precisam ser criptografados antes do armazenamento em bancos de dados. Para esse cenário, recomenda-se o uso de criptografia simétrica.
Operações de API relacionadas
|
Operação de API |
Descrição |
|
Criptografa texto simples usando uma chave simétrica. |
|
|
Descriptografa texto cifrado usando uma chave simétrica. |
Código de exemplo
Criptografar dados (Encrypt)
O código de exemplo a seguir mostra como chamar a operação Encrypt para criptografar texto simples em texto cifrado usando uma chave simétrica.
package com.aliyun.sample;
import com.aliyun.kms20160120.Client;
import com.aliyun.kms20160120.models.EncryptRequest;
import com.aliyun.kms20160120.models.EncryptResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
public class SymmetricEncryptSample {
public static Client createClient() throws Exception {
// Initialize the client with the AccessKey ID and AccessKey Secret obtained from environment variables.
// Make sure the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
Config config = new Config()
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// Set the dedicated gateway endpoint.
config.endpoint = "<Your-KMS-Instance-Endpoint>";
// Set the CA certificate of the KMS instance.
config.ca = "<Your-CA-Certificate-Content>";
return new Client(config);
}
public static void main(String[] args) throws Exception {
Client client = createClient();
// The plaintext to encrypt.
String plaintext = "this is a test message.";
EncryptRequest encryptRequest = new EncryptRequest()
// Set the ID of the symmetric key to use.
.setKeyId("<Your-Symmetric-Key-Id>")
// Set the plaintext to encrypt.
.setPlaintext(plaintext);
try {
// Call the Encrypt operation.
EncryptResponse response = client.encryptWithOptions(encryptRequest, new RuntimeOptions());
// Get the Base64-encoded ciphertext from the response.
String ciphertextBlob = response.getBody().getCiphertextBlob();
System.out.println("Plaintext: " + plaintext);
System.out.println("Ciphertext (Base64): " + ciphertextBlob);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Descriptografar dados (Decrypt)
O código de exemplo a seguir mostra como chamar a operação Decrypt para descriptografar texto cifrado em texto simples.
package com.aliyun.sample;
import com.aliyun.kms20160120.Client;
import com.aliyun.kms20160120.models.DecryptRequest;
import com.aliyun.kms20160120.models.DecryptResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
public class SymmetricDecryptSample {
public static Client createClient() throws Exception {
// The client initialization logic is the same as the encryption sample.
Config config = new Config()
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
config.endpoint = "<Your-KMS-Instance-Endpoint>";
config.ca = "<Your-CA-Certificate-Content>";
return new Client(config);
}
public static void main(String[] args) throws Exception {
Client client = createClient();
// The ciphertext to decrypt. It must be a Base64-encoded string returned by the Encrypt operation.
String ciphertextBlob = "<Ciphertext-From-Encryption-Step>";
DecryptRequest decryptRequest = new DecryptRequest()
// Set the ciphertext to decrypt.
.setCiphertextBlob(ciphertextBlob);
try {
// Call the Decrypt operation.
DecryptResponse response = client.decryptWithOptions(decryptRequest, new RuntimeOptions());
// Get the decrypted plaintext from the response.
String plaintext = response.getBody().getPlaintext();
System.out.println("Ciphertext (Base64): " + ciphertextBlob);
System.out.println("Decrypted Plaintext: " + plaintext);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Cenário 2: Aplicações implantadas dentro e fora da Alibaba Cloud
Recomenda-se o uso de criptografia assimétrica em cenários onde os dados são criptografados fora da Alibaba Cloud e descriptografados dentro dela.
Aplicações implantadas fora da Alibaba Cloud usam a chave pública para criptografar os dados e enviam o texto cifrado para as aplicações na Alibaba Cloud.
Após receber o texto cifrado, as aplicações na Alibaba Cloud chamam a instância do KMS para descriptografá-lo usando a chave privada.
Operações de API relacionadas
|
Operação de API |
Descrição |
|
Criptografa dados usando uma chave assimétrica. |
|
|
Descriptografa dados usando uma chave assimétrica. |
Código de exemplo
Criptografar
package com.aliyun.sample;
import com.aliyun.tea.*;
public class Sample {
/**
* <b>description</b> :
* <p>Initialize the account client with credentials</p>
* @return Client
*
* @throws Exception
*/
public static com.aliyun.kms20160120.Client createClient() throws Exception {
// We recommend using a more secure AK-free method for production code. For credential configuration, see: https://www.alibabacloud.com/help/document_detail/378657.html.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// Required. Make sure the environment variable ALIBABA_CLOUD_ACCESS_KEY_ID is set.
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
// Required. Make sure the environment variable ALIBABA_CLOUD_ACCESS_KEY_SECRET is set.
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
config.endpoint = "kst-hzz65f176a0ogplgq****.cryptoservice.kms.aliyuncs.com";
//KMS instance CA certificate
config.ca = "-----BEGIN CERTIFICATE-----MIIDuzCCAqOgAwIBAgIJALTKwWAjvbMiMA0GCS****";
return new com.aliyun.kms20160120.Client(config);
}
public static void main(String[] args) throws Exception {
com.aliyun.kms20160120.Client client = Sample.createClient();
com.aliyun.kms20160120.models.AsymmetricEncryptRequest asymmetricEncryptRequest = new com.aliyun.kms20160120.models.AsymmetricEncryptRequest()
.setPlaintext("test")
.setKeyId("a06e2410-*****-330777ee1825")
.setKeyVersionId("key-hzz65f17868e6cl0n****")
.setAlgorithm("RSAES_OAEP_SHA_256");
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
com.aliyun.kms20160120.models.AsymmetricEncryptResponse resp = client.asymmetricEncryptWithOptions(asymmetricEncryptRequest, runtime);
System.out.println(new com.google.gson.Gson().toJson(resp));
} catch (TeaException error) {
// This is for demonstration only. Handle exceptions carefully and do not ignore them in production.
// Error message
System.out.println(error.getMessage());
// Diagnostic URL
System.out.println(error.getData().get("Recommend"));
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// This is for demonstration only. Handle exceptions carefully and do not ignore them in production.
// Error message
System.out.println(error.getMessage());
// Diagnostic URL
System.out.println(error.getData().get("Recommend"));
}
}
}
Descriptografar
public class Sample {
/**
* <b>description</b> :
* <p>Initialize the account client with credentials</p>
* @return Client
*
* @throws Exception
*/
public static com.aliyun.kms20160120.Client createClient() throws Exception {
// Code leakage may lead to AccessKey leakage and threaten the security of all resources under the account. The following code is for reference only.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// Required. Make sure the environment variable ALIBABA_CLOUD_ACCESS_KEY_ID is set.
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
// Required. Make sure the environment variable ALIBABA_CLOUD_ACCESS_KEY_SECRET is set.
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// Dedicated gateway endpoint
config.endpoint = "kst-hzz65f176a0ogplgq****.cryptoservice.kms.aliyuncs.com";
//KMS instance CA certificate
config.ca = "-----BEGIN CERTIFICATE-----MIIDuzCCAqOgAwIBAgIJALTKwWAjvbMiMA0GCS****";
return new com.aliyun.kms20160120.Client(config);
}
public static void main(String[] args_) throws Exception {
com.aliyun.kms20160120.Client client = Sample.createClient();
com.aliyun.kms20160120.models.AsymmetricDecryptRequest asymmetricDecryptRequest = new com.aliyun.kms20160120.models.AsymmetricDecryptRequest()
.setKeyId("a06e2410-*****-330777ee1825")
.setKeyVersionId("key-hzz65f17868e6cl0n****")
.setAlgorithm("RSAES_OAEP_SHA_256")
.setCiphertextBlob("FV9i23PQdpGPvc*********MA==");
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
com.aliyun.kms20160120.models.AsymmetricDecryptResponse resp = client.asymmetricDecryptWithOptions(asymmetricDecryptRequest, runtime);
System.out.println(new com.google.gson.Gson().toJson(resp));
} catch (TeaException error) {
// This is for demonstration only. Handle exceptions carefully and do not ignore them in production.
// Error message
System.out.println(error.getMessage());
// Diagnostic URL
System.out.println(error.getData().get("Recommend"));
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// This is for demonstration only. Handle exceptions carefully and do not ignore them in production.
// Error message
System.out.println(error.getMessage());
// Diagnostic URL
System.out.println(error.getData().get("Recommend"));
}
}
}