Node/Mongo/AWS环境调用ClientEncryption.createDataKey()遇'expiration'字段错误
我的Node v18服务器应用部署在运行Amazon Linux 2023的AWS Elastic Beanstalk EC2实例上,通过.ebextensions配置Mongo企业版仓库,安装了mongo-enterprise-cryptd二进制文件以支持mongo-client-encryption Node库,用于验证显式加密、隐式解密字段。
初始化代码将KMS提供商设为AWS,值为空对象{},触发AWS在运行时通过IAM角色注入环境变量。截至2023年12月,Mongo尚未发布适用于Amazon Linux 2023的libmongocrypt包,因此我从源码编译了该库,随后安装并启动mongocryptd进程,再安装mongo-client-encryption驱动,过程中无缺失包报错。
在初始化加密密钥库数据库时,调用ClientEncryption.createDataKey()时捕获到错误:
MongoCryptError: Unexpected field: 'expiration'
我的代码未定义加密schema,KMS/连接选项及mongoose schema中均无expiration字段。
疑问
- 是否是Amazon在Mongo Node驱动获取KMS凭证时注入了该字段?
- 若不是,该字段来自何处?
- 如何解决或绕过无关字段检查?
已尝试操作
- 使用“合适的”配置选项调用
ClientEncryption.createDataKey()方法
预期与实际结果
- 预期:成功创建数据加密密钥(DEK)并继续执行代码
- 实际:收到不存在于代码库中的
expiration字段错误
是否是Amazon注入
expiration字段?
是。当通过IAM角色自动获取AWS KMS凭证时,AWS返回的临时凭证中包含expiration字段,但旧版本的mongo-client-encryption驱动或你编译的libmongocrypt版本对KMS响应的字段校验过于严格,无法识别这个额外字段,从而抛出错误。字段来源
该字段来自AWS IAM返回的临时安全凭证,属于AWS STS响应的标准字段,用于标识凭证的过期时间。解决/绕过方案
- 升级驱动与依赖库版本:优先尝试升级
mongo-client-encryption到最新稳定版,同时确保编译的libmongocrypt是对应驱动要求的最新版本——新版本已经修复了对AWS STS响应中额外字段的兼容问题。 - 手动指定KMS凭证(临时方案):如果暂时无法升级,可以手动获取AWS STS临时凭证(包含
AccessKeyId、SecretAccessKey、SessionToken),在代码中直接传入KMS配置,而非依赖IAM角色自动注入,这样可避免驱动接收到包含expiration字段的完整响应。 - 修改libmongocrypt源码(极端方案):若必须使用当前版本,可修改
libmongocrypt中处理AWS KMS响应的代码,忽略expiration字段后重新编译。
内容的提问来源于stack exchange,提问作者Angus Ryer

