更新时间:2026-08-18 GMT+08:00
分享

使用密钥胶囊进行加解密

应用场景

对大型文件、图片等数据通过HTTPS请求到KMS服务进行保护时会消耗大量网络资源,降低加密效率。

解决方案

加密SDK通过文件流分段信封加密的原理进行加密。

数据加密通过KMS生成的数据密钥在SDK内部进行,内存中分段加解密文件无需将数据通过网络传输后再进行加解密,保证了文件加密的安全性和正确性。

对于大型文件,SDK执行加密过程中,将文件分段读取到内存中,通过加解密写到目标文件后再进行下一段文件读取和加解密,直至完成整个文件的加解密。

配置说明

  • KMSConfig(KMS 配置)

    字段

    类型

    必填

    说明

    region

    String

    KMS区域,如cn-north-4

    keyId

    String

    KMS对称主密钥 ID

    projectId

    String

    项目ID

    endpoint

    String

    KMS端点,如 https://kms.cn-north-4.myhuaweicloud.com

    支持多个 region,加密时按顺序选择:

    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")
    );

    重要:KeyCapsuleConfig.region必须是kmsConfigList中已配置的region。KMSConfig支持配置多个region,但KeyCapsuleConfig只能配置一个region,且该region必须在 kmsConfigList中存在。

  • AccessPointConfig(接入点配置)

    字段

    类型

    必填

    说明

    type

    int

    接入点类型:

    • 1=ECS
    • 2=Custom(通用)
    • 3=CCE

    encryptedPrivateKey

    String

    否(type=2时,必填)

    加密的私钥(Base64 编码)

    privateKeyDecryptCallback

    PrivateKeyDecryptCallback

    否(type=2时,必填)

    私钥解密回调,用户实现解密逻辑,返回明文私钥的Base64 编码

    serviceAccount

    String

    CCE场景的ServiceAccount名称,默认default

  • KeyCapsuleConfig(密钥胶囊配置)

    字段

    类型

    必填

    说明

    region

    String

    创建/解密密钥胶囊的region

    defaultPolicyId

    String

    默认策略ID(EncryptRequest 未指定策略时使用)

    defaultKeyPolicy

    String

    默认内联策略JSON(优先级低于 defaultPolicyId)

    accessPointConfig

    AccessPointConfig

    接入点配置

  • HuaweiConfig(全局配置)

    字段

    类型

    必填

    说明

    ak

    String

    华为云Access Key

    sk

    String

    华为云Secret Key

    cryptoAlgorithm

    CryptoAlgorithm

    加密算法(加密时必填,解密时自动从密文头解析)

    kmsConfigList

    List<KMSConfig>

    加密时必填

    KMS配置列表(解密时无需传入)

    keyCapsuleConfig

    KeyCapsuleConfig

    密钥胶囊配置

    logConfig

    LogConfig

    LTS日志上报配置

    localLogOnly

    boolean

    是否仅本地打印日志(不上报 LTS),默认false

  • EncryptRequest(加密请求)

    字段

    类型

    必填

    说明

    plainText

    byte[]

    待加密的明文

    policyId

    String

    本次加密使用的策略ID(覆盖defaultPolicyId)

    keyPolicy

    String

    本次加密使用的内联策略JSON(覆盖defaultKeyPolicy)

  • LTS 日志上报(可选)
    • 启用日志上报
      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();
    • 仅本地打印日志(不上报 LTS)
      HuaweiConfig config = HuaweiConfig.builder()
              .ak(ak).sk(sk)
              .cryptoAlgorithm(CryptoAlgorithm.AES_256_GCM_NOPADDING)
              .kmsConfigList(kmsConfigList)
              .keyCapsuleConfig(keyCapsuleConfig)
              .localLogOnly(true)
              .build();
    • LogConfig 配置说明

      字段

      默认值

      说明

      logGroupName

      DSC

      日志组名称

      logStreamName

      crypto_operation_log

      日志流名称

      region

      -

      LTS服务区域(必填)

      projectId

      -

      项目ID(必填)

      batchCountThreshold

      1000

      缓冲区记录条数阈值

      lingerMs

      30000

      异步上报间隔(毫秒)

      batchSizeThresholdInBytes

      524288

      批量大小阈值(字节)

      ioThreadCount

      CPU 核数

      IO线程数

      totalSizeInBytes

      104857600

      缓冲区大小上限(100MB)

      maxBlockMs

      0

      发送阻塞时间(毫秒),0=不阻塞

      retries

      5

      重试次数

      baseRetryBackoffMs

      100

      首次重试退避时间(毫秒)

      maxRetryBackoffMs

      500

      最大重试退避时间(毫秒)

      backupDir

      ~/lts_log_backup

      失败日志备份目录

      enableRecoveryOnStartup

      true

      启动时恢复失败日志

      recoveryBatchSize

      1000

      恢复批量大小

      recoveryBatchInterval

      1000

      恢复批次间隔(毫秒)

  • 缓存(可选)
    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);

    配置项

    默认值

    说明

    capacity

    -

    最大缓存容量,超出按LRU淘汰

    maxByteLimit

    Long.MAX_VALUE

    单个数据密钥加密byte最大数量

    maxMessageLimit

    Integer.MAX_VALUE

    单个数据密钥加密数据条数最大限制

    survivalTime

    1000000

    缓存存活时间(毫秒)

  • 安全建议
    • AK/SK不应硬编码在代码中,建议从环境变量或密钥管理服务获取。
    • privateKeyDecryptCallback中应实现安全的私钥解密逻辑,避免明文存储私钥。

操作步骤

  1. 获取AK/SK:

    • ACCESS_KEY:华为账号Access Key,获取方式请参见获取AK/SK
    • SECRET_ACCESS_KEY:华为账号Secret Access Key,获取方式请参见获取AK/SK
    • PROJECT_ID:局点项目ID,获取方式请参见获取项目ID
    • KMS_ENDPOINT:华为云KMS服务访问终端地址,获取方式请参见终端节点
    • 认证用的ak和sk直接写到代码中有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全。
    • 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。

  2. 获取region相关信息。

    1. 登录DEW服务控制台
    2. 鼠标移动至右上方的用户名,在下拉列表中选择“我的凭证”
    3. 获取“项目ID”(PROJECT_ID)和“项目”(REGION)。
      图1 获取项目ID和项目
    4. 单击页面左侧,选择安全与合规 > 密码安全中心 DEW,默认进入“密钥管理”界面。
    5. 获取当前Region需要使用的主密钥ID(KEYID)。
      图2 获取主密钥ID

    6. 获取当前Region需要使用的终端节点(ENDPOINT)。

      终端节点(Endpoint)即调用API的请求地址,不同服务不同区域的终端节点不同,您可以从地区和终端节点中查询服务的终端节点。

      图3 获取终端节点

  3. 加解密。

    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. 鉴权信息(建议从环境变量获取)
            String ak = System.getenv("CLOUD_SDK_AK");
            String sk = System.getenv("CLOUD_SDK_SK");
    
            // 2. KMS 配置
            List<KMSConfig> kmsConfigList = Collections.singletonList(
                new KMSConfig("cn-north-7", "your_key_id", "your_project_id", "https://kms.cn-north-7.myhuaweicloud.com")
            );
    
            // 3. 接入点配置
            AccessPointConfig accessPointConfig = AccessPointConfig.builder()
                    .type(2)  // 1:ECS, 2:Custom, 3:CCE
                    .encryptedPrivateKey("your_encrypted_private_key")
                    .privateKeyDecryptCallback(encryptedKey -> {
                        // 用户实现回调解密私钥,返回 Base64 格式的明文私钥
                        return "your_plain_private_key";
                    })
                    .build();
    
            // 4. 密钥胶囊配置
            KeyCapsuleConfig keyCapsuleConfig = KeyCapsuleConfig.builder()
                    .region("cn-north-7")
                    .defaultPolicyId("your_policy_id")
                    .defaultKeyPolicy(null)  // 可选,优先使用 defaultPolicyId
                    .accessPointConfig(accessPointConfig)
                    .build();
    
            // 5. 构建加密配置
            HuaweiConfig config = HuaweiConfig.builder()
                    .ak(ak)
                    .sk(sk)
                    .cryptoAlgorithm(CryptoAlgorithm.AES_256_GCM_NOPADDING)
                    .kmsConfigList(kmsConfigList)
                    .keyCapsuleConfig(keyCapsuleConfig)
                    .build();
    
            // 6. 创建密钥胶囊密钥环并初始化 SDK
            KMSKeyring keyring = new KmsKeyringFactory().getKeyring(KeyringTypeEnum.KMS_KEY_CAPSULE.getType());
            HuaweiCrypto crypto = new HuaweiCrypto(config).withKeyring(keyring);
    
            // 7. 加密
            EncryptRequest encryptRequest = new EncryptRequest();
            encryptRequest.setPlainText("Hello, Key Capsule!".getBytes(StandardCharsets.UTF_8));
            CryptoResult<byte[]> result = crypto.encrypt(encryptRequest);
    
            // 8. 构建解密配置(解密无需 kmsConfigList)
            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. 解密
            CryptoResult<byte[]> decryptResult = decryptCrypto.decrypt(result.getResult());
            System.out.println(new String(decryptResult.getResult(), StandardCharsets.UTF_8));
        }
    }

相关文档