For assets deployed on Alibaba Cloud or other cloud environments that are assigned public IP addresses, sensitive data must be securely stored and transmitted to reduce breach risks and meet compliance requirements. For small amounts of sensitive data, you can use Key Management Service (KMS) to perform online encryption and decryption. This topic describes the scenarios, prerequisites, and procedures for online encryption and decryption.
Scope
The data size for symmetric encryption or decryption does not exceed 6 KB per operation.
The data size for asymmetric encryption or decryption does not exceed 1 KB per operation.
A larger data size for a single encryption operation increases the probability of network transmission failures and prolongs the transmission time. The time required for a KMS instance to perform encryption and decryption on the data also increases.
Key security
Do not store encryption keys in frontend code. Frontend JavaScript code is fully delivered to the user's browser, and key values can be viewed and extracted through browser developer tools. Whether it is a symmetric key, the private key of an asymmetric key, or an AccessKey used to access KMS, once embedded in frontend code, it is considered compromised. After a key is leaked, attackers can decrypt all historical ciphertext, rendering the encryption protection ineffective.
The recommended approach is to keep all key materials on the backend and consolidate encryption and decryption operations on the backend:
The frontend transmits sensitive data to the backend server over HTTPS, where TLS ensures confidentiality during transmission.
The backend server calls the KMS
EncryptorAsymmetricEncryptoperation to encrypt the data and stores the ciphertext in databases or other storage.When plaintext is needed, the backend calls the
DecryptorAsymmetricDecryptoperation to decrypt the data and returns the result to the frontend as needed.
With this architecture, key materials remain hosted within the KMS instance and never leave the KMS boundary. The backend holds only the credentials to access KMS, and the frontend never touches keys.
Preparation
Before you start calling APIs for encryption and decryption, complete the following preparation.
Step 1: Purchase and enable a KMS instance
Purchase and enable a KMS instance (software key management instance or hardware key management instance) based on your business requirements and compliance needs. For more information, see Purchase and enable a KMS instance.
Step 2: Create a key
Create a key in the enabled KMS instance based on your encryption scenario.
Symmetric key: used for encryption and decryption within a trusted environment.
Asymmetric key: used for scenarios that cross trust boundaries, for example, the client uses a public key to encrypt and the server uses a private key to decrypt.
For more information, see Create a key.
Step 3: Prepare access credentials and permissions
This topic uses AccessKey as an example. For more information about access credentials, see Create access credentials.
By default, an Alibaba Cloud account has administrator permissions for all resources, which cannot be modified. To ensure resource security, we recommend that you use a RAM user to create an AccessKey pair and grant it only the necessary permissions.
Log on to the RAM console. On the Users page, click the name of the target RAM user.
On the Secret Management tab, in the AccessKey section, click Create AccessKey.
Grant the RAM user permissions to access KMS.
Method 1: Configure an identity-based policy
In the Actions column of the RAM user, click Grant Permission to attach a built-in system permission policy for KMS to the RAM user. For more information about the system permission policies for KMS, see System policies for KMS.
NoteYou can also create custom permission policies. For more information, see Create a custom policy.
Method 2: Configure a resource-based policy
KMS supports resource-based policies that grant access permissions for individual keys and secrets. You can use these policies to control which Alibaba Cloud accounts, RAM users, and RAM roles can manage or use KMS keys and secrets. For more information, see Key policies and Secret policies.
Step 4: Obtain connection information and CA certificate
When calling APIs, you need to select the appropriate gateway endpoint based on your network environment.
This topic uses the dedicated gateway by default.
Feature | Shared gateway | Dedicated gateway |
Endpoint |
|
|
CA certificate | Not required. | Required. |
Applicable scenario | Public access, development and testing. | VPC internal access, production environments, higher performance and isolation. |
How to obtain | For more information, see Alibaba Cloud SDK. | On the instance details page, download the instance CA certificate and obtain the instance VPC endpoint. |
Application scenarios
Scenario 1: Applications deployed on Alibaba Cloud
Applications deployed on Alibaba Cloud generate or receive sensitive data in plaintext. The sensitive data must be encrypted before being stored in databases. We recommend using symmetric encryption for this scenario.
Related API operations
API operation | Description |
Encrypts plaintext by using a symmetric key. | |
Decrypts ciphertext by using a symmetric key. |
Sample code
Encrypt data (Encrypt)
The following sample code shows how to call the Encrypt operation to encrypt plaintext into ciphertext by using a symmetric key.
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();
}
}
}Decrypt data (Decrypt)
The following sample code shows how to call the Decrypt operation to decrypt ciphertext into plaintext.
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();
}
}
}Scenario 2: Applications deployed on and outside Alibaba Cloud
We recommend using asymmetric encryption for scenarios where data is encrypted outside Alibaba Cloud and decrypted on Alibaba Cloud.
Applications deployed outside Alibaba Cloud use the public key to encrypt data and send the ciphertext to applications on Alibaba Cloud.
After receiving the ciphertext, applications on Alibaba Cloud call the KMS instance to decrypt it by using the private key.
Related API operations
API operation | Description |
Encrypts data by using an asymmetric key. | |
Decrypts data by using an asymmetric key. |
Sample code
Encrypt
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"));
}
}
}Decrypt
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 {
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"));
}
}
}