翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
HTTP クエリベースのリクエストの使用時に Amazon SNS メッセージの署名を確認する
HTTP クエリベースのリクエストを使用する際に Amazon SNS メッセージの署名を検証すると、メッセージの信頼性と整合性が保証されます。このプロセスでは、メッセージが Amazon SNS から発信され、転送中に改ざんされていないことを確認します。メッセージの解析、署名用の正しい文字列の作成、信頼できるパブリックキーによる署名の検証を行うことで、なりすましや不正なメッセージ変更からシステムを保護できます。
-
Amazon SNS から送信された HTTP POST リクエストの本文で、JSON ドキュメントからキーと値のペアを抽出します。これらのフィールドは、署名文字列を作成するために必要です。
-
Message -
Subject(存在する場合) -
MessageId -
Timestamp -
TopicArn -
Type
例えば、次のようになります。
MESSAGE_FILE="message.json" FIELDS=("Message" "MessageId" "Subject" "Timestamp" "TopicArn" "Type")注記
いずれかのフィールドにエスケープ文字 (
\nなど) が含まれている場合は、それらの文字を元の形式に変換して、正確な一致が確実に行われるようにします。 -
-
Amazon SNS メッセージで
SigningCertURLフィールドを見つけます。この証明書には、メッセージ署名の検証に必要なパブリックキーが含まれています。例えば、次のようになります。SIGNING_CERT_URL=$(jq -r '.SigningCertURL' "$MESSAGE_FILE") -
SigningCertURLが信頼された AWS ドメイン ( など) からのものであることを確認しますhttps://sns.us-east-1.amazonaws.com。セキュリティ上の理由から、 AWS ドメイン外の URLs。 -
指定された URL から X.509 証明書をダウンロードします。例えば、次のようになります。
curl -s "$SIGNING_CERT_URL" -o signing_cert.pem -
ダウンロードした X.509 証明書からパブリックキーを抽出します。パブリックキーを使用すると、メッセージの署名を復号化して、その整合性を検証できます。例えば、次のようになります。
openssl x509 -pubkey -noout -in signing_cert.pem > public_key.pem -
メッセージタイプが異なると、署名文字列に含めるキーと値のペアも異なります。メッセージタイプ (Amazon SNS メッセージ内の
Typeフィールド) を特定して、含めるキーと値のペアを決定します。-
通知メッセージ –
Message、MessageId、Subject(存在する場合)、Timestamp、TopicArn、およびTypeが含まれます。 -
SubscriptionConfirmation または UnsubscribeConfirmation メッセージ –
Message、MessageId、SubscribeURL、Timestamp、Token、TopicArn、およびTypeが含まれます。
-
-
Amazon SNS では、検証を行うために、署名文字列は厳格で固定されたフィールドの順序に従う必要があります。明示的な必須フィールドのみを含める必要があり、追加のフィールドを加えることはできません。
Subjectなどのオプションフィールドは、そのフィールドがメッセージ内に存在する場合にのみ含める必要があり、必須フィールドの順序で定義された正確な位置に含める必要があります。例えば、次のようになります。KeyNameOne\nValueOne\nKeyNameTwo\nValueTwo重要
文字列の末尾に改行文字を追加しないでください。
-
キーと値のペアをバイト順でソートし、並べます (キー名に基づくアルファベット順)。
-
次の形式の例を使用して、署名文字列を作成します。
STRING_TO_SIGN="" for FIELD in "${FIELDS[@]}"; do VALUE=$(jq -r --arg field "$FIELD" '.[$field]' "$MESSAGE_FILE") STRING_TO_SIGN+="$FIELD\n$VALUE" # Append a newline after each field except the last one if [[ "$FIELD" != "Type" ]]; then STRING_TO_SIGN+="\n" fi done通知メッセージの例:
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 NotificationSubscriptionConfirmation の例:
Message Please confirm your subscription MessageId 3d891288-136d-417f-bc05-901c108273ee SubscribeURL https://sns.us-east-2.amazonaws.com/... Timestamp 2024-01-01T00:00:00.000Z Token abc123... TopicArn arn:aws:sns:us-east-2:123456789012:MyTopic Type SubscriptionConfirmation -
メッセージ内の
Signatureフィールドは Base64 でエンコードされています。未加工のバイナリ形式と、派生したハッシュを比較するために、このフィールドをデコードする必要があります。例えば、次のようになります。SIGNATURE=$(jq -r '.Signature' "$MESSAGE_FILE") echo "$SIGNATURE" | base64 -d > signature.bin -
SignatureVersionフィールドを使用してハッシュアルゴリズムを選択します。-
SignatureVersion1 の場合 SHA1 を使用します (例:-sha1)。 -
SignatureVersion2 の場合 SHA256 を使用します (例:-sha256)。
-
-
Amazon SNS メッセージの信頼性を確認するには、作成された文字列のハッシュを生成し、パブリックキーを使用して署名を検証します。
openssl dgst -sha256 -verify public_key.pem -signature signature.bin <<< "$STRING_TO_SIGN"署名が有効な場合、出力は
Verified OKになります。それ以外の場合、出力はVerification Failureになります。
エラー処理を使用したスクリプトの例
次のスクリプト例では、検証プロセスを自動化します。
#!/bin/bash
# Path to the local message file
MESSAGE_FILE="message.json"
# Extract the SigningCertURL and Signature from the message
SIGNING_CERT_URL=$(jq -r '.SigningCertURL' "$MESSAGE_FILE")
SIGNATURE=$(jq -r '.Signature' "$MESSAGE_FILE")
# Fetch the X.509 certificate
curl -s "$SIGNING_CERT_URL" -o signing_cert.pem
# Extract the public key from the certificate
openssl x509 -pubkey -noout -in signing_cert.pem > public_key.pem
# Define the fields to include in the string to sign
FIELDS=("Message" "MessageId" "Subject" "Timestamp" "TopicArn" "Type")
# Initialize the string to sign
STRING_TO_SIGN=""
# Iterate over the fields to construct the string to sign
for FIELD in "${FIELDS[@]}"; do
VALUE=$(jq -r --arg field "$FIELD" '.[$field]' "$MESSAGE_FILE")
STRING_TO_SIGN+="$FIELD\n$VALUE"
# Append a newline after each field except the last one
if [[ "$FIELD" != "Type" ]]; then
STRING_TO_SIGN+="\n"
fi
done
# Verify the signature
echo -e "$STRING_TO_SIGN" | openssl dgst -sha256 -verify public_key.pem -signature <(echo "$SIGNATURE" | base64 -d)