

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Memverifikasi tanda tangan pesan Amazon SNS
<a name="sns-verify-signature-of-message"></a>

Amazon SNS menggunakan tanda tangan pesan untuk mengonfirmasi keaslian pesan yang dikirim ke titik akhir HTTP Anda. Untuk memastikan integritas pesan dan mencegah spoofing, Anda **harus** memverifikasi tanda tangan sebelum memproses pesan Amazon SNS apa pun.

**Kapan Anda harus memverifikasi tanda tangan Amazon SNS?**

Anda harus memverifikasi tanda tangan pesan Amazon SNS dalam skenario berikut:
+ Saat Amazon SNS mengirim pesan notifikasi ke titik akhir HTTP (S) Anda.
+ Saat Amazon SNS mengirim pesan konfirmasi ke titik akhir Anda setelah panggilan [https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html)atau [https://docs.aws.amazon.com/sns/latest/api/API_Unsubscribe.html](https://docs.aws.amazon.com/sns/latest/api/API_Unsubscribe.html)API.

**Amazon SNS mendukung dua versi tanda tangan:**
+ SignatureVersion1 — Menggunakan SHA1 hash dari pesan.
+ SignatureVersion2 — Menggunakan SHA256 hash dari pesan. Ini memberikan keamanan yang lebih kuat dan merupakan opsi yang disarankan.

**Untuk memverifikasi tanda tangan pesan SNS dengan benar, ikuti praktik terbaik berikut:**
+ Selalu ambil sertifikat penandatanganan menggunakan HTTPS untuk mencegah serangan intersepsi yang tidak sah.
+ Periksa apakah sertifikat dikeluarkan oleh Amazon SNS.
+ Konfirmasikan bahwa rantai kepercayaan sertifikat valid.
+ Sertifikat harus berasal dari URL yang ditandatangani SNS.
+ Jangan percaya sertifikat apa pun yang diberikan dalam pesan tanpa validasi.
+ Tolak pesan apa pun dengan yang tidak terduga `TopicArn` untuk mencegah spoofing.
+  AWS SDKs Untuk Amazon SNS menyediakan logika validasi bawaan, mengurangi risiko kesalahan penyederhanaan.

# Mengonfigurasi versi tanda tangan pesan pada topik Amazon SNS
<a name="sns-verify-signature-of-message-configure-message-signature"></a>

Mengonfigurasi versi tanda tangan pesan pada topik Amazon SNS memungkinkan Anda meningkatkan keamanan dan kompatibilitas proses verifikasi pesan Anda.

Pilih antara `SignatureVersion` **1** (SHA1) dan `SignatureVersion` **2** (SHA256) untuk mengontrol algoritma hashing yang digunakan untuk menandatangani pesan. **Topik Amazon SNS default ke `SignatureVersion` 1.** Anda dapat mengonfigurasi pengaturan ini menggunakan tindakan [https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html](https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html)API.

Gunakan contoh berikut untuk mengatur atribut topik `SignatureVersion` menggunakan AWS CLI:

```
aws sns set-topic-attributes \
    --topic-arn arn:aws:sns:us-east-2:123456789012:MyTopic \
    --attribute-name SignatureVersion \
    --attribute-value 2
```

# Memverifikasi tanda tangan pesan Amazon SNS saat menggunakan permintaan berbasis kueri HTTP
<a name="sns-verify-signature-of-message-verify-message-signature"></a>

Memverifikasi tanda tangan pesan Amazon SNS saat menggunakan permintaan berbasis kueri HTTP memastikan keaslian dan integritas pesan. Proses ini menegaskan bahwa pesan tersebut berasal dari Amazon SNS dan belum dirusak selama transit. Dengan mengurai pesan, membuat string yang benar untuk ditandatangani, dan memvalidasi tanda tangan terhadap kunci publik tepercaya, Anda melindungi sistem Anda dari spoofing dan perubahan pesan yang tidak sah.

1. Ekstrak **pasangan kunci-nilai** dari dokumen JSON di badan permintaan HTTP POST yang dikirim oleh Amazon SNS. Bidang ini diperlukan untuk membangun **string untuk ditandatangani**.
   + `Message`
   + `Subject`(jika ada)
   + `MessageId`
   + `Timestamp`
   + `TopicArn`
   + `Type`

   Contoh:

   ```
   MESSAGE_FILE="message.json"
   FIELDS=("Message" "MessageId" "Subject" "Timestamp" "TopicArn" "Type")
   ```
**catatan**  
Jika ada bidang yang berisi karakter yang diloloskan (misalnya,`\n`), konversikan ke **bentuk aslinya** untuk memastikan kecocokan yang tepat.

1. Temukan `SigningCertURL` bidang di pesan Amazon SNS. Sertifikat ini berisi kunci publik yang diperlukan untuk memverifikasi tanda tangan pesan. Contoh:

   ```
   SIGNING_CERT_URL=$(jq -r '.SigningCertURL' "$MESSAGE_FILE")
   ```

1. Pastikan berasal dari AWS domain tepercaya (misalnya,https://sns.us-east-1.amazonaws.com). `SigningCertURL` Tolak ** AWS domain URLs luar** apa pun untuk alasan keamanan.

1. Unduh **sertifikat X.509 dari URL** yang disediakan. Contoh:

   ```
   curl -s "$SIGNING_CERT_URL" -o signing_cert.pem
   ```

1. Ekstrak **kunci publik** dari sertifikat X.509 yang diunduh. Kunci publik memungkinkan Anda untuk mendekripsi tanda tangan pesan dan memverifikasi integritasnya. Contoh:

   ```
   openssl x509 -pubkey -noout -in signing_cert.pem > public_key.pem
   ```

1. Jenis pesan yang berbeda memerlukan pasangan kunci-nilai yang berbeda dalam string untuk ditandatangani. Identifikasi **jenis pesan** (`Type`bidang dalam pesan Amazon SNS) untuk menentukan pasangan **nilai kunci** mana yang akan disertakan:
   + **Pesan pemberitahuan** — Termasuk`Message`,`MessageId`, `Subject` (jika ada),`Timestamp`,`TopicArn`, dan`Type`.
   + **SubscriptionConfirmation**atau **UnsubscribeConfirmation pesan** — Termasuk`Message`,`MessageId`,`SubscribeURL`,`Timestamp`,`Token`,`TopicArn`, dan`Type`.

1. Amazon SNS memerlukan string untuk menandatangani untuk mengikuti urutan bidang yang ketat dan tetap untuk verifikasi. **Hanya bidang yang diperlukan secara eksplisit yang harus disertakan** —tidak ada bidang tambahan yang dapat ditambahkan. Bidang opsional`Subject`, seperti, harus disertakan hanya jika ada dalam pesan dan harus muncul di posisi yang tepat yang ditentukan oleh urutan bidang yang diperlukan. Contoh:

   ```
   KeyNameOne\nValueOne\nKeyNameTwo\nValueTwo
   ```
**penting**  
Jangan menambahkan karakter baris baru di akhir string.

1. Atur **pasangan kunci-nilai** dalam urutan byte-sort (menurut abjad dengan nama kunci).

1. Membangun **string untuk menandatangani** menggunakan contoh format berikut:

   ```
   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
   ```

   **Contoh pesan pemberitahuan:**

   ```
   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 contoh:**

   ```
   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
   ```

1. `Signature`Bidang dalam pesan adalah Base64-dikodekan. Anda perlu **mendekodekannya** untuk membandingkan **bentuk biner mentahnya** dengan **hash turunan**. Contoh:

   ```
   SIGNATURE=$(jq -r '.Signature' "$MESSAGE_FILE")
   echo "$SIGNATURE" | base64 -d > signature.bin
   ```

1. Gunakan `SignatureVersion` bidang untuk memilih algoritma hash:
   + Untuk `SignatureVersion` **1**, gunakan **SHA1**(misalnya,`-sha1`).
   + Untuk `SignatureVersion` **2**, gunakan **SHA256**(misalnya,`-sha256`).

1. **Untuk mengonfirmasi keaslian pesan Amazon SNS, buat hash dari string **yang** dibangun dan verifikasi tanda tangan menggunakan kunci publik.**

   ```
   openssl dgst -sha256 -verify public_key.pem -signature signature.bin <<< "$STRING_TO_SIGN"
   ```

   Jika tanda tangan valid, outputnya adalah`Verified OK`. Jika tidak, outputnya adalah`Verification Failure`.

## Contoh skrip dengan penanganan kesalahan
<a name="sns-verify-signature-of-message-example"></a>

Contoh skrip berikut mengotomatiskan proses verifikasi:

```
#!/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)
```