如何验证SNS消息来自可信源并限制API网关仅接收指定SNS消息
如何验证AWS SNS消息来源是否为信任的SNS主题
你对SNS签名的作用理解有偏差:这套签名机制不仅能验证消息未被篡改,同时也能验证消息确实由合法的AWS SNS服务发出,而非第三方伪造,因为签名使用的私钥仅由AWS SNS持有,第三方无法生成能通过公钥校验的有效签名。你只需要按以下步骤执行校验,就能确保仅接收你信任的SNS主题的消息:
完整校验步骤
- 校验签名证书URL合法性
首先要拒绝所有不符合规则的SigningCertURL,避免攻击者传入自定义域名下的伪造证书绕过校验:必须确保该URL的域名为sns.<你预期的AWS区域>.amazonaws.com格式,与你的SNS主题所在区域完全匹配,路径为AWS官方SNS证书的固定路径格式。校验通过后再下载证书,建议本地缓存合法证书,无需每次请求都重复下载。 - 提取证书公钥
从PEM格式的SNS签名证书中提取RSA公钥,用于后续签名校验。 - 按官方规则构造待签名字符串
SNS的签名不是对完整JSON消息直接签名,需要根据消息类型按固定顺序拼接指定字段:
对于你收到的Notification类型消息,需要按Message、MessageId、Subject(如果消息中存在该字段才加)、Timestamp、TopicArn、Type的顺序拼接,每个字段名后跟换行符,对应字段值后跟换行符,无对应字段不要添加。 - 校验消息签名
针对消息中的SignatureVersion: '1'场景,使用提取到的公钥,对上面构造的待签名字符串做SHA1哈希签名校验,将校验结果与Signature字段Base64解码后的值对比,二者一致则签名合法,说明消息确实由AWS SNS发出且未被篡改。 - 校验信任主题ARN
签名通过仅能证明消息是AWS SNS发出的,你还需要将消息中的TopicArn字段值与你预设的信任SNS主题ARN列表对比,仅匹配的请求才放行,即可避免其他非预期的合法SNS主题发来的消息。
可选加固方案
- 你可以在SNS主题侧配置访问策略,仅允许你信任的账号/服务向该主题发布消息,进一步降低风险
- 若使用
SignatureVersion: '2',需使用SHA256算法做签名校验,安全性更高
内容的提问来源于stack exchange,提问作者Mooncrater
相关产品推荐
相关产品推荐

