调用AWS decrypt解密时出现InvalidCiphertextException: null报错如何解决
报错根因
InvalidCiphertextException是AWS KMS服务返回的明确错误,代表传入的密文不符合KMS可解析的格式,你遇到的问题核心是密文已经在存储/传输过程中被损坏,你打印的Buffer中大量出现的ef bf bd是UTF-8解码失败的替换字符,直接证明了密文字节已经被篡改。
其他可能的触发原因包括:
- 加密时使用的KMS密钥、区域、账号,和当前解密环境配置不一致
- 当前使用的AK/SK没有对应KMS密钥的
kms:Decrypt权限 - 传入解密方法的参数不是加密时返回的原始
CiphertextBlob
排查步骤
- 核对环境配置:确认当前环境的
AWS_REGION、DATA_KEY_ARN、AK/SK和加密时使用的配置完全一致,检查KMS密钥的权限策略是否给当前账号开放了解密权限 - 核对密文完整性:加密后直接记录
CiphertextBlob的字节长度,解密前再打印传入参数的字节长度,两者长度不一致即可确认密文被篡改 - 检查编码逻辑:排查加密后存储密文、解密前读取密文的流程,是否存在将二进制Buffer错误转成UTF-8字符串的操作
修复方案
步骤1:统一密文存储编码
加密后将二进制密文转成Base64字符串存储,避免传输、存储过程中的编码错误,修改加密方法:
const encrypt = async content => kms.encrypt({ KeyId: process.env.DATA_KEY_ARN, Plaintext: content, }).promise() .then(data => data.CiphertextBlob.toString('base64')) // 转Base64字符串后再返回存储 .catch(err => console.log(err, err.stack));
步骤2:调整解密流程
解密前先将Base64格式的密文转回原始二进制Buffer,再传入KMS解密接口,同时修正解密后的转码逻辑(KMS返回的Plaintext就是明文Buffer,不需要额外做Base64解码):
const decryptComment = async (comment) => { // 兼容Buffer和Base64字符串两种入参格式 const encryptedBuffer = Buffer.isBuffer(comment) ? comment : Buffer.from(comment, 'base64'); const plaintextBuffer = await decrypt(encryptedBuffer); // 直接转明文即可 return plaintextBuffer.toString('ascii'); };
内容的提问来源于stack exchange,提问作者Bisma
相关产品推荐
相关产品推荐

