验证 Amazon SNS 消息的签名 - Amazon Simple Notification Service

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

验证 Amazon SNS 消息的签名

要验证 Amazon 发送到您的HTTP终端节点的消息的真实性SNS,您可以验证消息签名。在两种情况下,我们建议验证消息的真实性。首先,当 Amazon SNS 向您的HTTP终端节点发送消息表示您订阅了某个主题时。其次,当 Amazon 在执行SubscribeUnsubscribeAPI操作后SNS向您发送确认消息到您的HTTP终端节点时。

在验证 Amazon 发送的消息时,您应执行以下操作SNS:

  • 从 Amazon 获取证书HTTPS时请务必使用SNS。

  • 验证证书的真伪。

  • 验证证书是否已从 Amazon 收到SNS。

  • 如果可能,请使用 Amazon 支持的 AWS SDKs方法之一SNS来验证和验证消息。

  • 验证是否收到了您想要的 Amazon SNS 消息TopicArn

Amazon SNS 支持两种消息签名版本:

  • SignatureVersion1:Amazon 根据消息的SHA1哈希值SNS创建签名。

  • SignatureVersion2:Amazon 根据消息的SHA256哈希值SNS创建签名。

在 Amazon SNS 主题上配置消息签名版本

默认情况下,Amazon SNS 主题使用 SignatureVersion 1。要在 Amazon SNS 主题上选择哈希算法(SignatureVersion1 (SHA1) 或 SignatureVersion 2 (SHA256)),您可以使用SetTopicAttributesAPI操作。

以下代码示例显示如何使用 AWS 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 消息的签名
  1. 从 Amazon SNS 发送到您的终端节点的HTTPPOST请求正JSON文中的文档中提取名称/值对。您将使用名称/值对中的一些值来创建待签字符串。在验证 Amazon SNS 消息的签名时,必须将转义的控制字符转换为其在MessageSubject值中的原始字符表示形式。当您将上述值用作待签字符串一部分时,上述值必须保留原始形式。有关如何解析JSON文档的信息,请参见第 1 步:确保您的终端节点已准备就绪,可以处理 Amazon SNS 消息

    SignatureVersion告诉您 Amazon SNS 生成消息签名时使用的签名版本。通过签名版本,您可以确定生成签名的要求。对于通知,Amazon SNS 目前支持签名版本 12。本部分提供验证使用这些签名版本的签名的步骤。

  2. 获取亚马逊SNS用来签署邮件的 X509 证书。指向 X509 证书位置的 SigningCertURL 值用于创建消息的数字签名。检索此位置上的证书。

  3. 从此证书上提取公钥。来自 SigningCertURL 所指定证书的公钥用于验证信息的真实性和完整性。

  4. 确定消息类型。待签字符串格式取决于消息类型,该类型由 Type 值指定。

  5. 创建待签字符串。待签字符串为来自消息的特定名称-值对换行符逗号分隔列表。各个名称/值对由值后面换行符之后的第一个名称表示,以换行符为结尾。名称/值对必须以字节排序顺序予以列明。

    根据消息类型,待签字符串必须具有以下名称/值对。

    通知

    通知消息必须含有以下名称/值对:

    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

    SubscriptionConfirmationUnsubscribeConfirmation 消息必须包含以下名称/值对:

    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 Token 233... TopicArn arn:aws:sns:us-east-2:123456789012:s4-MySNSTopic-1G1WEFCOXTC0P Type SubscriptionConfirmation
  6. 通过 Base64 格式解码 Signature 值。消息传递以 Signature 值表示的签名,并将该签名编码为 Base64。将签名值与您计算出的签名进行对比前,应确保您已通过 Base64 完成对 Signature 值的解码操作,然后才能将运用相同格式的值进行对比。

  7. 生成 Amazon SNS 消息的派生哈希值。使用与生成签名相同的哈希算法,以规范格式提交 Amazon SNS 消息。

    1. 如果SignatureVersion1,则SHA1用作哈希算法。

    2. 如果SignatureVersion2,则SHA256用作哈希算法。

  8. 生成 Amazon SNS 消息的断言哈希值。断言的哈希值是使用公钥值(来自步骤 3)解密随着 Ama SNS zon 消息传送的签名的结果。

  9. 验证 Amazon SNS 消息的真实性和完整性。比较派生的哈希值(来自步骤 7)与断言的哈希值(来自步骤 8)。如果值相同,则可以向接收者保证,消息在传输过程中未被修改,并且消息必须来自亚马逊SNS。如果值不相同,则接收人不应信任它。