MassTransit开启UseEncryption后AWS SNS/SQS消息无法投递问题排查
MassTransit.AmazonSQS UseEncryption与SNS/SQS兼容问题解决方案
问题根因
该问题是MassTransit 7.2.2版本AmazonSQS组件的加密实现逻辑和AWS SNS/SQS的消息体规范不兼容导致的:
- AWS SNS/SQS要求消息体必须是符合XML 1.0规范的合法UTF-8字符,仅允许ASCII码为
0x9(制表符)、0xA(换行符)、0xD(回车符)以及大于等于0x20的可打印字符,禁止出现其他控制字符。 - MassTransit 7.2.2版本的默认
UseEncryption实现,会直接将加密后的原始二进制字节写入消息体,加密生成的二进制数据大概率包含不符合要求的控制字符,触发SNS返回InvalidMessageContents错误,导致消息无法从SNS投递到SQS,消费者自然收不到消息。
之前调整密钥生成方式、对密钥做Base64转码的操作没有效果,因为问题出在加密后的消息体格式,和密钥本身的格式无关。
解决方案
方案1:升级MassTransit版本
MassTransit从8.0版本开始已经官方修复了该问题,AmazonSQS组件的加密逻辑默认会将加密后的二进制数据做Base64编码后再写入消息体,完全兼容AWS SNS/SQS的字符规范。直接将生产、消费两端的MassTransit.AmazonSQS包升级到最新稳定版本,保持两端加密密钥一致即可解决问题,无需修改业务逻辑。
方案2:自定义加密逻辑(无法升级版本时使用)
如果受项目约束无法升级MassTransit版本,可以自行实现加密序列化逻辑适配AWS规范:
- 实现MassTransit的
ICryptoStreamProvider接口,在加密写入逻辑中,将加密后的二进制字节数组转换为Base64字符串后再写入消息体 - 在解密读取逻辑中,先将消息体的Base64字符串转换回二进制字节数组,再执行解密操作
- 在总线配置中替换默认的加密流提供者为自定义实现,保持两端密钥和转码逻辑一致即可
内容的提问来源于stack exchange,提问作者diegosasw
相关产品推荐
相关产品推荐

