本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
验证 Amazon SNS 消息签名
要验证 Amazon SNS 发送到您的 HTTP 端点的消息的真实性,您可以验证消息签名。在两种情况下,我们建议验证消息的真实性。第一种,当 Amazon SNS 向您的 HTTP 端点发送一条消息,说明您订阅了某个主题时。第二种,当 Amazon SNS 在执行 Subscribe
或者 Unsubscribe
API 操作后,向您的 HTTP 端点发送确认消息时。
您在验证 Amazon SNS 发送的消息时应执行以下操作:
-
从 Amazon SNS 获取证书时始终使用 HTTPS。
-
验证证书的真伪。
-
验证证书是否是从 Amazon SNS 收到的。
-
尽可能使用适用于 Amazon SNS 的某个受支持 Amazon SDK 来验证消息。
-
验证是否收到来自所需
TopicArn
的 Amazon SNS 消息。
Amazon SNS 支持两种消息签名版本:
-
SignatureVersion
1:Amazon SNS 基于消息的 SHA1 哈希创建签名。 -
SignatureVersion
1:Amazon SNS 基于消息的 SHA256 哈希创建签名。
在 Amazon SNS 主题上配置消息签名版本
默认情况下,Amazon SNS 主题使用 SignatureVersion
1。要在 Amazon SNS 主题上选择哈希算法 SignatureVersion
1 (SHA1) 或 SignatureVersion
2 (SHA256),可以使用 SetTopicAttributes
API 操作。
以下代码示例显示如何使用 Amazon CLI 设置主题属性 SignatureVersion
:
aws sns set-topic-attributes \
--topic-arn arn:aws:sns:us-east-2:123456789012:MyTopic \
--attribute-name SignatureVersion \
--attribute-value 2
在使用基于 HTTP 查询的请求时验证 Amazon SNS 消息的签名
-
从 Amazon SNS 向终端节点发送的 HTTP POST 请求正文的 JSON 文档中提取名称/值对。您将使用名称/值对中的一些值来创建待签字符串。当您正在验证 Amazon SNS 消息签名时,应将转义控制字符转换成其在
Message
和Subject
值中的原始字符表示,这点很重要。当您将上述值用作待签字符串一部分时,上述值必须保留原始形式。有关如何分析 JSON 文档的信息,请参阅 步骤 1:确保您的终端节点已准备好处理 Amazon SNS 消息。SignatureVersion
告知您 Amazon SNS 生成消息签名所用的签名版本。通过签名版本,您可以确定生成签名的要求。对于通知,Amazon SNS 当前支持签名版本 1 和 2。本部分提供验证使用这些签名版本的签名的步骤。 -
获取 Amazon SNS 用于签署消息的 X509 证书。指向 X509 证书位置的
SigningCertURL
值用于创建消息的数字签名。检索此位置上的证书。 -
从此证书上提取公钥。来自
SigningCertURL
所指定证书的公钥用于验证信息的真实性和完整性。 -
确定消息类型。待签字符串格式取决于消息类型,该类型由
Type
值指定。 -
创建待签字符串。待签字符串为来自消息的特定名称-值对换行符逗号分隔列表。各个名称/值对由值后面换行符之后的第一个名称表示,以换行符为结尾。名称/值对必须以字节排序顺序予以列明。
根据消息类型,待签字符串必须具有以下名称/值对。
- 通知
-
通知消息必须含有以下名称/值对:
Message MessageId Subject (if included in the message) Timestamp TopicArn Type
以下为针对
Notification
待签字符串的一个示例。Message My Test Message MessageId 4d4dc071-ddbf-465d-bba8-08f81c89da64 Subject My subject Timestamp 2019-01-31T04:37:04.321Z TopicArn arn:aws:sns:us-east-2:123456789012:s4-MySNSTopic-1G1WEFCOXTC0P Type Notification
- SubscriptionConfirmation 和 UnsubscribeConfirmation
-
SubscriptionConfirmation
和UnsubscribeConfirmation
消息必须包含以下名称/值对:Message MessageId SubscribeURL Timestamp Token TopicArn Type
以下为针对
SubscriptionConfirmation
待签字符串的一个示例。Message My Test Message MessageId 3d891288-136d-417f-bc05-901c108273ee SubscribeURL https://sns.us-east-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-east-2:123456789012:s4-MySNSTopic-1G1WEFCOXTC0P&Token=
233...
Timestamp 2019-01-31T19:25:13.719Z Token233...
TopicArn arn:aws:sns:us-east-2:123456789012:s4-MySNSTopic-1G1WEFCOXTC0P Type SubscriptionConfirmation
-
通过 Base64 格式解码
Signature
值。消息传递以Signature
值表示的签名,并将该签名编码为 Base64。将签名值与您计算出的签名进行对比前,应确保您已通过 Base64 完成对Signature
值的解码操作,然后才能将运用相同格式的值进行对比。 -
生成 Amazon SNS 消息的派生哈希值。以规范格式将 Amazon SNS 消息提交给用于生成签名的相同哈希算法。
-
如果
SignatureVersion
为 1,则使用 SHA1 作为哈希算法。 -
如果
SignatureVersion
为 2,则使用 SHA256 作为哈希算法。
-
-
生成 Amazon SNS 消息的断言哈希值。断言的哈希值为使用公有密钥值(来自步骤 3)对随 Amazon SNS 消息发布的签名进行解码得到的结果。
-
验证 Amazon SNS 信息的真实性和完整性。比较派生的哈希值(来自步骤 7)与断言的哈希值(来自步骤 8)。如果值相同,则接收人可确定消息在传输过程中未被修改,并且消息一定是源自 Amazon SNS。如果值不相同,则接收人不应信任它。