Updated on 2026-09-20 GMT+08:00

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).

  • (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

  1. 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.

  2. Obtain region information.

    1. Log in to the DEW console.
    2. Hover over the username in the upper right corner and choose My Credentials from the drop-down list.
    3. Obtain the project ID and project name.
      Figure 1 Obtaining the project ID and project name
    4. Click on the left and choose Security & Compliance > Data Encryption Workshop.
    5. Obtain the ID of the CMK (KEYID) to be used in the current region.
      Figure 2 Obtaining the CMK ID

    6. Obtain the endpoint (ENDPOINT) required by the current region.
      Figure 3 Obtaining an endpoint

  3. 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));
        }
    }