使用密钥胶囊进行加解密
应用场景
对大型文件、图片等数据通过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中应实现安全的私钥解密逻辑,避免明文存储私钥。
操作步骤
- 获取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。
- 获取region相关信息。
- 登录DEW服务控制台。
- 鼠标移动至右上方的用户名,在下拉列表中选择“我的凭证”。
- 获取“项目ID”(PROJECT_ID)和“项目”(REGION)。 图1 获取项目ID和项目
- 单击页面左侧
,选择,默认进入“密钥管理”界面。 - 获取当前Region需要使用的主密钥ID(KEYID)。 图2 获取主密钥ID

- 获取当前Region需要使用的终端节点(ENDPOINT)。
终端节点(Endpoint)即调用API的请求地址,不同服务不同区域的终端节点不同,您可以从地区和终端节点中查询服务的终端节点。
图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)); } }