署名メッセージ

SMS APIでは、SMSメッセージの送受信時に署名を使用できます。送信時には、メッセージと共に送信する署名を生成します。受信時には、受信ウェブフックに署名と、アプリケーションで署名を生成するために必要なすべてのフィールドが含まれ、2つの署名が一致することを検証します。

あなたはサインを使う:

  • リクエストが信頼できるソースから発信されたものであることを検証する。
  • メッセージが途中で改ざんされていないことを確認する。
  • インターセプトとリプレーに対する防御

内容

この文書では、送信するメッセージへの署名と、受信するメッセージに正しい署名があるかどうかのVerifyの両方について、メッセージでの署名の使い方を説明します。

メッセージ送信時に署名を使用する

署名付きメッセージを送信するには SIGNATURE_SECRET の代わりに API_SECRET メッセージの送信時に署名の秘密を見つけ、どの署名アルゴリズムを使うかを選択するには ダッシュボード.デフォルトのアルゴリズムはMD5ハッシュをサポートする。 MD5 HMAC, SHA1 HMAC, SHA-256 HMAC そして SHA-512 HMAC.

Vonageでは、次のいずれかを使用することを強くお勧めします。 クライアントライブラリ を使用して署名を生成または検証します。もし かなわない なぜかこうする。 シグネチャを自分で生成して検証することもできますが、これは複雑で、エラーが発生する可能性があります。そのため 署名を手動で生成するセクション.

署名付きメッセージの送信プロセスは以下の通り:

  1. 署名入り リクエスト でSMSを送信する。
  2. チェック レスポンスコード リクエストを正しく送信したことを確認してください。
  3. メッセージが携帯電話に届きます。利用者の携帯電話から配信レシートが返送されます。
  4. (オプション) 署名入りの配送受領書と受信メッセージを要求した場合、各受信リクエストの署名を検証したいでしょう。

署名を正しく生成できなかった場合 ステータス14, invalid signature.詳細は トラブルシューティング の項を参照されたい。

デフォルトでは、メッセージ送信時の署名はオプションで、受信ウェブフックには含まれません。署名付き Webhook を有効にする、または送信されたメッセージにすべて署名するようにするには、次の連絡先までお問い合わせください。 サポート.

以下のコード例は、SMS APIを使って署名付きメッセージを送信する方法を示している。

前提条件

npm install @vonage/server-sdk

send-signed-sms.js という名前のファイルを作成し、以下のコードを追加する:

const { Vonage } = require('@vonage/server-sdk');

const vonage = new Vonage({
  apiKey: VONAGE_API_KEY,
  apiSecret: VONAGE_API_SECRET,
  // By passing in the signature, the SDK will sign the request for you
  // Isn't that neat?!
  signature: {
    secret: SMS_SIGNATURE,
    algorithm: 'md5hash',
  },
});

全文を見る

コードを書く

send-signed-sms.js に以下を追加する:

const sendMessage = async () => {
  try {
    const result = await vonage.sms.send({
      from: SMS_SENDER_ID,
      to: SMS_TO_NUMBER,
      text: 'A text message sent using the Vonage SMS API',
    });

    console.log('Message sent successfully.');
    console.log(result);
  } catch (error) {
    console.error(`Message failed with error: ${error.message}`);
  }
};

sendMessage();

全文を見る

コードを実行する

このファイルをあなたのマシンに保存し、実行する:

node send-signed-sms.js

前提条件

build.gradle に以下を追加する:

implementation 'com.vonage:server-sdk-kotlin:2.1.1'

SendSignedSms という名前のファイルを作成し、main メソッドに以下のコードを追加する:

fun main() {
    val client = Vonage {
        apiKey(VONAGE_API_KEY)
        signatureSecret(VONAGE_SIGNATURE_SECRET)
        hashType(HashType.HMAC_SHA256)

全文を見る

コードを書く

SendSignedSms ファイルのmain メソッドに以下を追加する:


val response = client.sms.sendText(
    from = SMS_SENDER_ID,
    to = SMS_TO_NUMBER,
    message = "Hello from Vonage SMS API"
)

if (response.wasSuccessfullySent()) {
    println("Message sent successfully.")
}
else {
    println("Message failed with error: ${response[0].errorText}")

全文を見る

コードを実行する

Gradle用のアプリケーション プラグインを使うことで、アプリケーションの実行を簡単にすることができます。build.gradle を以下のように更新する:

apply plugin: 'application'
mainClassName = project.hasProperty('main') ? project.getProperty('main') : ''

以下のgradle コマンドを実行し、com.vonage.quickstart.kt.smsSendSignedSms を含むパッケージに置き換えてアプリケーションを実行する:

gradle run -Pmain=com.vonage.quickstart.kt.sms.SendSignedSms

前提条件

build.gradle に以下を追加する:

implementation 'com.vonage:server-sdk:9.3.1'

SendSignedSms という名前のファイルを作成し、main メソッドに以下のコードを追加する:

import com.vonage.client.VonageClient;
import com.vonage.client.auth.hashutils.HashType;
import com.vonage.client.sms.MessageStatus;
import com.vonage.client.sms.SmsSubmissionResponse;
import com.vonage.client.sms.messages.TextMessage;

全文を見る

SendSignedSms ファイルのmain メソッドに以下を追加する:

);

SmsSubmissionResponse response = client.getSmsClient().submitMessage(message);

全文を見る

コードを書く

SendSignedSms ファイルのmain メソッドに以下を追加する:

            System.out.println("Message sent successfully.");
        } else {
            System.out.println("Message failed with error: " + response.getMessages().get(0).getErrorText());
        }
    }
}

全文を見る

コードを実行する

Gradle用のアプリケーション プラグインを使うことで、アプリケーションの実行を簡単にすることができます。build.gradle を以下のように更新する:

apply plugin: 'application'
mainClassName = project.hasProperty('main') ? project.getProperty('main') : ''

以下のgradle コマンドを実行し、com.vonage.quickstart.smsSendSignedSms を含むパッケージに置き換えてアプリケーションを実行する:

gradle run -Pmain=com.vonage.quickstart.sms.SendSignedSms

前提条件

Install-Package Vonage

SendSignedSms.cs という名前のファイルを作成し、以下のコードを追加する:


var credentials = Credentials.FromApiKeySignatureSecretAndMethod(
    vonageApiKey,
    vonageApiSignatureSecret,
    Vonage.Cryptography.SmsSignatureGenerator.Method.md5hash
    );

全文を見る

コードを書く

SendSignedSms.cs に以下を追加する:

var credentials = Credentials.FromApiKeySignatureSecretAndMethod(
    vonageApiKey,
    vonageApiSignatureSecret,
    Vonage.Cryptography.SmsSignatureGenerator.Method.md5hash
    );

var vonageClient = new VonageClient(credentials);

var response = await vonageClient.SmsClient.SendAnSmsAsync(new Vonage.Messaging.SendSmsRequest()
{
    To = SMS_TO_NUMBER,
    From = SMS_SENDER_ID,
    Text = "This is a Signed SMS"
});

全文を見る

前提条件

composer require vonage/client

コードを書く

send-signed-sms.php に以下を追加する:

$signed = new \Vonage\Client\Credentials\SignatureSecret(
    VONAGE_API_KEY,
    VONAGE_API_SIGNATURE_SECRET,
    'md5hash'
);
$client = new \Vonage\Client($signed);

$response = $client->sms()->send(
    new \Vonage\SMS\Message\SMS(TO_NUMBER, FROM_NUMBER, 'Super interesting message')
);

echo "Message status: " . $response->current()->getStatus() . "\n";

全文を見る

コードを実行する

このファイルをあなたのマシンに保存し、実行する:

php send-signed-sms.php

前提条件

pip install vonage python-dotenv

コードを書く

send-signed-sms.py に以下を追加する:

from vonage import Auth, Vonage
from vonage_sms import SmsMessage, SmsResponse

client = Vonage(Auth(api_key=VONAGE_API_KEY, signature_secret=SMS_SIGNATURE))

message = SmsMessage(
    to=SMS_TO_NUMBER,
    from_=SMS_SENDER_ID,
    text="A text message sent using the Vonage SMS API.",
)

response: SmsResponse = client.sms.send(message)
print(response)

全文を見る

コードを実行する

このファイルをあなたのマシンに保存し、実行する:

python sms/send-signed-sms.py

受信メッセージの署名を検証する

SMSエンドポイントに着信するWebhookの発信元を確認するために、着信メッセージのメッセージ署名を有効にすることができます。 サポート を使用して、受信メッセージに署名を添付するよう要求できます。この設定を有効にすると、着信SMSと配達受信の両方のウェブフックに sig パラメータを使用する。リクエストの他のパラメータとあなたの署名シークレットを使って署名を生成し、 送られた署名と比較する。この2つが一致すれば、リクエストは有効である。

連絡先 サポート をクリックして、アカウントのメッセージ署名を有効にしてください。

以下のコード例は、受信SMSメッセージの署名をVerifyする方法を示している。 sig パラメーターをクエリー文字列に追加する。

前提条件

npm install express @vonage/server-sdk

コードを書く

verify-signed-sms.js に以下を追加する:

const { Vonage } = require('@vonage/server-sdk');

const app = require('express')();
const bodyParser = require('body-parser');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true,
}));

app
  .route('/webhooks/inbound-sms')
  .get(handleInboundSms)
  .post(handleInboundSms);

const  handleInboundSms = (request, response) => {
  const params = Object.assign(request.query, request.body);
  const { sig } = params;

  if (Vonage.sms.verifySignature(
    sig,
    params,
    VONAGE_SIGNATURE_SECRET,
    'md5hash', // one of md5hash, md5, sha1, sha256, or sha512
  )) {
    console.log('Valid signature');
  } else {
    console.log('Invalid signature');
  }

  response.status(204).send();
};

app.listen(process.env.PORT || 3000);

全文を見る

コードを実行する

このファイルをあなたのマシンに保存し、実行する:

node verify-signed-sms.js

前提条件

build.gradle に以下を追加する:

implementation 'com.vonage:server-sdk:9.3.1'

ReceiveSignedSms という名前のファイルを作成し、main メソッドに以下のコードを追加する:

import com.vonage.client.auth.RequestSigning;
import spark.Route;
import spark.Spark;

全文を見る

コードを書く

ReceiveSignedSms ファイルのmain メソッドに以下を追加する:

     * Route to handle incoming SMS GET request.
     */
    Route inboundSmsAsGet = (req, res) -> {
        String signatureSecret = VONAGE_SIGNATURE_SECRET;
        System.out.println(signatureSecret);
        if (RequestSigning.verifyRequestSignature(
                req.raw().getInputStream(),
                req.contentType(),
                req.queryMap().toMap(),
                signatureSecret
        )) {
            System.out.println("msisdn: " + req.queryParams("msisdn"));
            System.out.println("messageId: " + req.queryParams("messageId"));
            System.out.println("text: " + req.queryParams("text"));
            System.out.println("type: " + req.queryParams("type"));
            System.out.println("keyword: " + req.queryParams("keyword"));
            System.out.println("messageTimestamp: " + req.queryParams("message-timestamp"));

            res.status(204);    
        }
        else {
            System.out.println("Bad signature");
            res.status(401);
        }
        
        return "";
    };        

    Spark.port(5000);
    Spark.get("/webhooks/inbound-sms", inboundSmsAsGet);        
}

全文を見る

コードを実行する

Gradle用のアプリケーション プラグインを使うことで、アプリケーションの実行を簡単にすることができます。build.gradle を以下のように更新する:

apply plugin: 'application'
mainClassName = project.hasProperty('main') ? project.getProperty('main') : ''

以下のgradle コマンドを実行し、com.vonage.quickstart.smsReceiveSignedSms を含むパッケージに置き換えてアプリケーションを実行する:

gradle run -Pmain=com.vonage.quickstart.sms.ReceiveSignedSms

前提条件

Install-Package Vonage

SmsController.cs という名前のファイルを作成し、以下のコードを追加する:

{
    [HttpGet("webhooks/inbound-sms")]        

全文を見る

コードを書く

SmsController.cs に以下を追加する:

        public IActionResult VerifySms()
        {
            var vonageApiSignatureSecret = Environment.GetEnvironmentVariable("VONAGE_API_SIGNATURE_SECRET") ?? "VONAGE_API_SIGNATURE_SECRET";
            var sms = WebhookParser.ParseQuery<InboundSms>(Request.Query);
            if (sms.ValidateSignature(vonageApiSignatureSecret, Vonage.Cryptography.SmsSignatureGenerator.Method.md5hash))
            {
                Console.WriteLine("Signature is valid");
            }
            else
            {
                Console.WriteLine("Signature not valid");
            }
            return NoContent();
        }
    }
}

全文を見る

前提条件

composer require vonage/client

コードを書く

verify-signed-sms.php に以下を追加する:

$inbound = \Vonage\Message\InboundMessage::createFromGlobals();

if ($inbound->isValid()) {
    $params = $inbound->getRequestData();
    $signature = new Vonage\Client\Signature(
        $params,
        VONAGE_API_SIGNATURE_SECRET,
        'md5hash'
    );
    $validSig = $signature->check($params['sig']);

    if($validSig) {
        error_log("Valid signature");
    } else {
        error_log("Invalid signature");
    }

} else {
    error_log('Invalid message');
}

全文を見る

コードを実行する

このファイルをあなたのマシンに保存し、実行する:

php verify-signed-sms.php

前提条件

pip install vonage python-dotenv fastapi[standard]

コードを書く

main.py に以下を追加する:

import os
from os.path import dirname, join

from dotenv import load_dotenv

envpath = join(dirname(__file__), '../.env')
load_dotenv(envpath)

VONAGE_API_KEY = os.getenv("VONAGE_API_KEY")
VONAGE_SIGNATURE_SECRET = os.getenv("VONAGE_SIGNATURE_SECRET")

from fastapi import FastAPI, Request
from vonage import Auth, Vonage

client = Vonage(Auth(api_key=VONAGE_API_KEY, signature_secret=VONAGE_SIGNATURE_SECRET))

app = FastAPI()


@app.post('/')
async def verify_signed_webhook(request: Request):
    data = await request.json()

    if client.http_client.auth.check_signature(data):
        print('Valid signature')
    else:
        print('Invalid signature')

全文を見る

コードを実行する

このファイルをあなたのマシンに保存し、実行する:

fastapi dev sms/verify-signed-sms/main.py

:A POST リクエストにはクエリー文字列データも含まれる可能性があります。両方の POST とクエリ文字列データは、SMS APIではサポートされていないため、予期しない結果になる可能性があります。

手動で署名を生成する

それは 一押し 署名の生成と検証には、Vonageライブラリの既存の機能をご利用ください。この機能を持つライブラリを使用していない場合は、自分で署名を生成する必要があります。MD5ハッシュ」署名やHMAC署名のいずれかを生成する場合は、テクニックが若干異なります。

ステップ1:ハッシュ署名とHMAC署名の場合

もしあなたが 署名を生成する: 現在のタイムスタンプをパラメータリストに追加する。 timestamp.これは、エポックからの秒数を含む整数でなければなりません (これは UNIX 時間としても知られています)。

もしあなたが 署名の検証 をVonageから取り外します:を削除します。 sig パラメータを使用します。 timestamp リクエストパラメータで指定された

それからだ:

  • 各パラメーターをキー順にループする。
  • パラメータリストのすべての値に対して & そして = アンダースコア _.
  • で構成される文字列を生成する。 &akey=value&bkey=value. アンパサンド & を文字列の先頭に置く!

この時点で MD5 そして ハイマック ハッシュ法は異なる。以下のステップ2に従い、どのハッシュ技法を使うかを決める。

ステップ2

  • MD5ハッシュ

    1. 文字列の最後、最後の値の直後に署名の秘密を追加する。このようになります: &akey=value&bkey=valueyour_signature_secret
    2. 次に、この文字列をmd5ハッシュ関数に通し、結果のバイトを16進数の文字列に変換する。これがMD5ハッシュ署名となり、リクエストのHTTPパラメータに sig パラメータが必要だ。
  • ハイマック

    1. 希望するアルゴリズムと署名の秘密をキーとしてHMACジェネレーターを作成する。
    2. 次に、この文字列をHMACジェネレーターに通し、結果のバイトを16進数の文字列に変換する。これがHMAC署名で、リクエストのHTTPパラメータに sig パラメーター(例えば、PHPでは次のようになります。 hash_hmac($algorithm, $data, $secret)).

ステップ3:補足事項

シグネチャを生成する際にパラメータ値を変更したが、HTTPパラメータとして渡される値は以下のとおりであることに留意されたい。 むかしながら これらのパラメータをSMS APIに送信する場合。

シグネチャーのトラブルシューティング

署名入りのメッセージを扱う際の注意点と落とし穴をご紹介します。

詳細は回答を確認

メッセージが期待通りに送信されない場合は、レスポンスに以下のようなものがないかチェックする。 エラーコード が返された。そうすれば、次に何をすべきか、より詳しくわかるでしょう。

エラー14:無効な署名

送信されるテキストに次のような特殊文字が含まれている場合 & (アンパサンド)または = (equals)の場合、署名を作成するためのテキストでこれらを置き換える必要がある。

これを行うには、以下の手順を使用する:

  • テキストに以下の内容が含まれていることを確認する。 & または =.
  • を使用したテキストのバージョンを作成する。 _ (アンダースコア)をこれらの特殊文字の代わりに使用する。
  • 署名を作成するには、テキストのサニタイズ・バージョンを使用する。

元のテキストはそのまま送受信でき、文字の置き換えは署名を生成するためだけに必要である。