Using Key Capsules for Encryption and Decryption
Scenario
If large files and images are sent to KMS through HTTPS for encryption, a large number of network resources will be consumed and the encryption will be slow. This section describes how to quickly encrypt a large amount of data.
Solution
Encryption SDK performs envelope encryption on file streams segment by segment.
Data is encrypted within the SDK by using the DEK generated by KMS. Segmented encryption of files in the memory ensures the security and correctness of file encryption, as it does not require file transfer over the network.
The SDK loads a file to memory and processes it segment by segment. The next segment will not be read before the encryption or decryption of the current segment completes.
Configuration Description
- KMSConfig (KMS configuration)
Field
Type
Mandatory
Description
region
String
Yes
KMS region, for example, cn-north-4.
keyId
String
Yes
KMS symmetric master key ID.
projectId
String
Yes
Project ID.
endpoint
String
Yes
KMS endpoint, for example, https://kms.cn-north-4.myhuaweicloud.com.
Multiple regions are supported. Select regions in sequence during encryption.
List<KMSConfig> kmsConfigList = Arrays.asList( new KMSConfig("cn-north-4", "key_id_1", "project_id_1", "https://kms.cn-north-4.myhuaweicloud.com"), new KMSConfig("cn-south-1", "key_id_2", "project_id_2", "https://kms.cn-south-1.myhuaweicloud.com") );Important: KeyCapsuleConfig.region must be a region that has been configured in kmsConfigList. Multiple regions can be configured for KMSConfig, but only one region can be configured for KeyCapsuleConfig. The region must exist in kmsConfigList.
- AccessPointConfig (access point configuration)
Field
Type
Mandatory
Description
type
int
Yes
Access point type:
- 1=ECS
- 2=Custom (general)
- 3=CCE
encryptedPrivateKey
String
No (mandatory when type is set to 2)
Encrypted private key (Base64-encoded)
privateKeyDecryptCallback
PrivateKeyDecryptCallback
No (mandatory when type is set to 2)
Private key decryption callback. The user implements the decryption logic and the Base64-encoded plaintext private key is returned.
- KeyCapsuleConfig (key capsule configuration)
Field
Type
Mandatory
Description
region
String
Yes
Region where the key capsule is created or decrypted.
defaultPolicyId
String
Yes
Default policy ID (used when no policy is specified in EncryptRequest).
defaultKeyPolicy
String
Yes
Default inline policy JSON (with a higher priority than defaultPolicyId).
accessPointConfig
AccessPointConfig
Yes
Access point configuration
- HuaweiConfig (global configuration)
Field
Type
Mandatory
Description
ak
String
Yes
Huawei Cloud access key (AK)
sk
String
Yes
Huawei Cloud secret key (SK)
cryptoAlgorithm
CryptoAlgorithm
Yes
Encryption algorithm (mandatory for encryption and automatically parsed from the ciphertext header during decryption)
kmsConfigList
List<KMSConfig>
Mandatory for encryption
KMS configuration list (not required for decryption)
keyCapsuleConfig
KeyCapsuleConfig
Yes
Key capsule configuration
logConfig
LogConfig
No
LTS log reporting configuration
localLogOnly
boolean
No
Whether to print logs only locally (not reported to LTS). The default value is false.
- EncryptRequest (encryption request)
Field
Type
Mandatory
Description
plainText
byte[]
Yes
Plaintext to be encrypted.
policyId
String
No
ID of the policy used for encryption (overwriting defaultPolicyId).
keyPolicy
String
No
Inline policy JSON used for encryption (overwriting defaultKeyPolicy).
- (Optional) LTS log reporting
- Enable log reporting.
LogConfig logConfig = LogConfig.builder() .logGroupName("DSC") .logStreamName("crypto_operation_log") .region("cn-north-4") .projectId("your_project_id") .batchCountThreshold(1000) .lingerMs(30000) .batchSizeThresholdInBytes(524288) .ioThreadCount(4) .totalSizeInBytes(104857600) .maxBlockMs(0) .retries(5) .baseRetryBackoffMs(100) .maxRetryBackoffMs(500) .backupDir("/home/logbackup") .enableRecoveryOnStartup(true) .recoveryBatchSize(1000) .recoveryBatchInterval(1000) .build(); HuaweiConfig config = HuaweiConfig.builder() .ak(ak).sk(sk) .cryptoAlgorithm(CryptoAlgorithm.AES_256_GCM_NOPADDING) .kmsConfigList(kmsConfigList) .keyCapsuleConfig(keyCapsuleConfig) .logConfig(logConfig) .build(); - Print logs only locally (not reported to LTS).
HuaweiConfig config = HuaweiConfig.builder() .ak(ak).sk(sk) .cryptoAlgorithm(CryptoAlgorithm.AES_256_GCM_NOPADDING) .kmsConfigList(kmsConfigList) .keyCapsuleConfig(keyCapsuleConfig) .localLogOnly(true) .build(); - LogConfig configuration
Field
Default Value
Description
logGroupName
DSC
Log group name.
logStreamName
crypto_operation_log
Log stream name.
region
-
(Mandatory) LTS service region.
projectId
-
(Mandatory) Project ID.
batchCountThreshold
1,000
Threshold of records in the buffer.
lingerMs
30,000
Asynchronous reporting interval (ms).
batchSizeThresholdInBytes
524,288
Batch size threshold (byte).
ioThreadCount
Number of vCPUs
Number of I/O threads.
totalSizeInBytes
104,857,600
Maximum buffer size (100 MB).
maxBlockMs
0
Sending block time (ms). 0: not blocked.
retries
5
Number of retries.
baseRetryBackoffMs
100
First retry backoff time (ms).
maxRetryBackoffMs
500
Maximum retry backoff time (ms).
backupDir
~/lts_log_backup
Backup directory of failure logs.
enableRecoveryOnStartup
true
Restoration of failure logs upon startup.
recoveryBatchSize
1,000
Restoration batch size.
recoveryBatchInterval
1,000
Restoration batch interval (ms).
- Enable log reporting.
- (Optional) Cache
LocalDataKeyCache localDataKeyCache = new LocalDataKeyCache(); localDataKeyCache.setCapacity(10); CacheCryptoMeterialManager cacheManager = new CacheCryptoMeterialManager(localDataKeyCache, config); cacheManager.setMaxByteLimit(3000); cacheManager.setMaxMessageLimit(1000); cacheManager.setSurvivalTime(5000); crypto.withCryptoMeterialManager(cacheManager);
Configuration Item
Default Value
Description
capacity
-
Maximum cache capacity. If the capacity is exceeded, data is evicted based on the least recently used (LRU) algorithm.
maxByteLimit
Long.MAX_VALUE
Maximum number of bytes that can be encrypted using a single DEK.
maxMessageLimit
Integer.MAX_VALUE
Maximum number of data records that can be encrypted using a single DEK.
survivalTime
1,000,000
Cache time to live (TTL) (ms)
- Security suggestions
- The AK/SK should not be hard-coded. You are advised to obtain the AK/SK from environment variables or KMS.
- Implement secure private key decryption logic in privateKeyDecryptCallback to avoid private key storage in plaintext.
Procedure
- Obtain the AK/SK.
- ACCESS_KEY: Access key of the Huawei account. For details, see How Do I Obtain an Access Key (AK/SK)?
- SECRET_ACCESS_KEY: Secret access key of the Huawei account. For details, see How Do I Obtain an Access Key (AK/SK)?
- PROJECT_ID: site project ID. For details, see Obtaining a Project ID.
- KMS_ENDPOINT: endpoint for accessing KMS. For details, see Regions and Endpoints.
- There will be security risks if the AK/SK used for authentication is directly written into code. Encrypt the AK/SK in the configuration file or environment variables for storage.
- In this example, the AK/SK stored in the environment variables are used for identity authentication. Configure the environment variables HUAWEICLOUD_SDK_AK and HUAWEICLOUD_SDK_SK in the local environment first.
- Obtain region information.
- Log in to the DEW console.
- Hover over the username in the upper right corner and choose My Credentials from the drop-down list.
- Obtain the project ID and project name. Figure 1 Obtaining the project ID and project name
- Click
on the left and choose . - Obtain the ID of the CMK (KEYID) to be used in the current region. Figure 2 Obtaining the CMK ID

- Obtain the endpoint (ENDPOINT) required by the current region. Figure 3 Obtaining an endpoint
- Perform encryption and decryption.
import com.huaweicloud.encryptionsdk.HuaweiConfig; import com.huaweicloud.encryptionsdk.HuaweiCrypto; import com.huaweicloud.encryptionsdk.keyrings.KmsKeyringFactory; import com.huaweicloud.encryptionsdk.keyrings.kmskeyring.KMSKeyring; import com.huaweicloud.encryptionsdk.model.*; import com.huaweicloud.encryptionsdk.model.enums.CryptoAlgorithm; import com.huaweicloud.encryptionsdk.model.enums.KeyringTypeEnum; import com.huaweicloud.encryptionsdk.model.request.EncryptRequest; import java.nio.charset.StandardCharsets; import java.util.Collections; public class KeyCapsuleExample { public static void main(String[] args) { // 1. Authentication information (You are advised to obtain it from environment variables.) String ak = System.getenv("CLOUD_SDK_AK"); String sk = System.getenv("CLOUD_SDK_SK"); // 2. KMS configuration List<KMSConfig> kmsConfigList = Collections.singletonList( new KMSConfig("cn-north-7", "your_key_id", "your_project_id", "https://kms.cn-north-7.myhuaweicloud.com") ); // 3. Access point configuration AccessPointConfig accessPointConfig = AccessPointConfig.builder() .type(2) // 1:ECS, 2:Custom, 3:CCE .encryptedPrivateKey("your_encrypted_private_key") .privateKeyDecryptCallback(encryptedKey -> { // The user implements a callback to decrypt the private key. The Base64-encoded plaintext private key is returned. return "your_plain_private_key"; }) .build(); // 4. Key capsule configuration KeyCapsuleConfig keyCapsuleConfig = KeyCapsuleConfig.builder() .region("cn-north-7") .defaultPolicyId("your_policy_id") .defaultKeyPolicy(null) // Optional. defaultPolicyId is preferred. .accessPointConfig(accessPointConfig) .build(); // 5. Construct the encryption configuration. HuaweiConfig config = HuaweiConfig.builder() .ak(ak) .sk(sk) .cryptoAlgorithm(CryptoAlgorithm.AES_256_GCM_NOPADDING) .kmsConfigList(kmsConfigList) .keyCapsuleConfig(keyCapsuleConfig) .build(); // 6. Create a key capsule key ring and initialize the SDK. KMSKeyring keyring = new KmsKeyringFactory().getKeyring(KeyringTypeEnum.KMS_KEY_CAPSULE.getType()); HuaweiCrypto crypto = new HuaweiCrypto(config).withKeyring(keyring); // 7. Perform encryption. EncryptRequest encryptRequest = new EncryptRequest(); encryptRequest.setPlainText("Hello, Key Capsule!".getBytes(StandardCharsets.UTF_8)); CryptoResult<byte[]> result = crypto.encrypt(encryptRequest); // 8. Construct the decryption configuration. (kmsConfigList is not required for decryption.) HuaweiConfig decryptConfig = HuaweiConfig.builder() .ak(ak) .sk(sk) .keyCapsuleConfig(keyCapsuleConfig) .build(); KMSKeyring decryptKeyring = new KmsKeyringFactory().getKeyring(KeyringTypeEnum.KMS_KEY_CAPSULE.getType()); HuaweiCrypto decryptCrypto = new HuaweiCrypto(decryptConfig).withKeyring(decryptKeyring); // 9. Perform decryption. CryptoResult<byte[]> decryptResult = decryptCrypto.decrypt(result.getResult()); System.out.println(new String(decryptResult.getResult(), StandardCharsets.UTF_8)); } }
What is your overall rating for this page?
Thank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
For any further questions, feel free to contact us through the chatbot.
Chatbot