解密AWS Cognito自定义邮件触发器KMS加密码遇InvalidCiphertextException
解决AWS Cognito加密验证码Java解密触发
InvalidCiphertextException的问题 问题背景
通过CDK配置AWS Cognito用户池,使用自定义KMS密钥加密验证码,在customEmailSender触发器的Lambda中尝试解密时,Java代码调用KMS的Decrypt API持续触发InvalidCiphertextException,但用NodeJS的AWS Encryption SDK可以正常解密,AWS CLI执行解密命令也报同样错误。已确认Lambda拥有kms:Decrypt和kms:DescribeKey权限。
核心原因
Cognito在使用自定义KMS密钥加密验证码时,采用的是AWS Encryption SDK的封装加密格式,而非KMS原生Encrypt API生成的单纯密文。这种封装格式包含了密钥ID、加密上下文等元数据,无法直接通过KMS的Decrypt API解密,必须使用AWS Encryption SDK来处理。
解决方案:Java中使用AWS Encryption SDK解密
替换原来直接调用KmsClient的代码,改用AWS Encryption SDK for Java来解密:
1. 添加依赖(Maven为例)
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-encryption-sdk-java</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>kms</artifactId> <version>2.20.0</version> </dependency>
2. 修改解密代码
import com.amazonaws.encryptionsdk.AwsCrypto; import com.amazonaws.encryptionsdk.CommitmentPolicy; import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider; import java.util.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger log = LoggerFactory.getLogger(YourLambdaClass.class); private String keyArn; // 从环境变量或配置中注入 private String decryptCode(String encryptedCode) { // 初始化AWS加密SDK,与NodeJS使用一致的承诺策略 AwsCrypto crypto = AwsCrypto.builder() .withCommitmentPolicy(CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT) .build(); // 创建KMS主密钥提供者,指定目标密钥ARN KmsMasterKeyProvider keyProvider = KmsMasterKeyProvider.builder() .withKeysForEncryption(keyArn) .build(); // 解码Base64密文 byte[] encryptedData = Base64.getDecoder().decode(encryptedCode); // 解密并返回明文 String decrypted = crypto.decryptString(keyProvider, encryptedData).getResult(); log.info("DecryptedData {}", decrypted); return decrypted; }
验证说明
- 该代码逻辑与NodeJS版本完全对齐,都是使用AWS Encryption SDK处理Cognito生成的封装加密格式
- 无需手动调用KMS的Decrypt API,SDK会自动解析密文中的元数据、匹配密钥并完成解密
内容的提问来源于stack exchange,提问作者Alexiz Hernandez
相关产品推荐
相关产品推荐

