Amazon SNS メッセージの署名を検証する
Amazon SNS で HTTP エンドポイントに送信されたメッセージの信頼性を検証するには、メッセージの署名を検証できます。メッセージの信頼性の検証を推奨するケースは 2 つあります。まず、Amazon SNS が HTTP エンドポイントに対して、トピックにサブスクライブしたというメッセージを送信するときです。2 つ目は、Subscribe
または Unsubscribe
API アクションの実行時に Amazon SNS が HTTP エンドポイントに確認メッセージを送信する場合です。
Amazon SNS によって送信されたメッセージを検証するときに、以下のオペレーションを行う必要があります。
-
Amazon SNS から証明書を取得するときは必ず HTTPS を使用する
-
証明書の信頼性を検証する
-
証明書が Amazon SNS から受信されたことを確認する。
-
可能であれば、サポートされている Amazon SNS 用の AWS SDK のいずれかを使用してメッセージを検証および確認する。
-
Amazon SNS メッセージが希望する
TopicArn
から受信されていることを検証します。
Amazon SNS は次の 2 つのメッセージ署名バージョンをサポートしています。
-
SignatureVersion
1: Amazon SNS は、メッセージの SHA1 ハッシュに基づいて署名を作成します。 -
SignatureVersion
2: Amazon SNS は、メッセージの SHA256 ハッシュに基づいて署名を作成します。
Amazon SNS トピックでメッセージ署名バージョンを設定するには
Amazon SNS トピックは、デフォルトで SignatureVersion
1 を使用します。Amazon SNS トピックのハッシュアルゴリズム、SignatureVersion
1 (SHA1) または SignatureVersion
2 (SHA256) を選択するには、SetTopicAttributes
API アクションを使用できます。
次のコード例は、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 メッセージの署名を確認するには
-
Amazon SNS がエンドポイントに送信した HTTP POST リクエストの本文で、JSON ドキュメントから名前と値のペアを抽出します。署名対象の文字列を作成するために、名前と値のペアの一部の値を使用します。Amazon SNS メッセージの署名を確認する場合は、
Message
およびSubject
の値で、エスケープした制御文字を元の文字表現に変換し直すことが重要です。これらの値では、署名対象の文字列の一部として使用するときに、元の形式になっている必要があります。JSON ドキュメントを解析する方法の詳細については、「ステップ 1: エンドポイントで Amazon SNS メッセージを処理する準備が完了していることを確認する」を参照してください。SignatureVersion
は、Amazon SNS がメッセージの署名を生成するために使用する署名バージョンを示します。署名バージョンからは、署名を生成する方法の要件を判断できます。通知では、Amazon SNS は現在、署名バージョン 1 および 2 をサポートしています。このセクションでは、これらの署名バージョンを使用して署名を作成する手順を説明します。 -
メッセージの署名に Amazon SNS が使用した X509 証明書を取得します。
SigningCertURL
値は、メッセージのデジタル署名の作成に使用された X509 証明書の場所を指します。この場所から証明書を取得します。 -
証明書から公開キーを抽出します。
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
値をデコードします。メッセージは、Base64 としてエンコードされたSignature
値で署名を配信します。署名の値を、計算した署名と比較する前に、Base64 からSignature
の値をデコードし、同じ形式を使って値を比較します。 -
Amazon SNS メッセージの派生したハッシュ値を生成します。署名の生成に使用されるのと同じハッシュアルゴリズムに、正規形式で Amazon SNS メッセージを送信します。
-
SignatureVersion
が 1 のとき SHA1 をハッシュアルゴリズムとして使用します。 -
SignatureVersion
が 2 のとき SHA256 をハッシュアルゴリズムとして使用します。
-
-
Amazon SNS メッセージのアサートされたハッシュ値を生成します。アサートされたハッシュ値は、Amazon SNS メッセージで配信された署名を復号するために (ステップ 3 の) 公開キーバリューを使用した結果です。
-
Amazon SNS メッセージの信頼性と整合性を確認します。(ステップ 7 から) 派生したハッシュ値を、(ステップ 8 から) アサートされたハッシュ値に比較します。値が同じ場合、受信者はメッセージが転送中に変更されておらず、メッセージが Amazon SNS から発信されたことを確認できます。値が同じでない場合、受信者はこれを信頼することはできません。