Signature des messages

Vous pouvez utiliser des signatures avec l'API SMS lors de l'envoi et de la réception de messages SMS. Lors de l'envoi, vous générez une signature à envoyer avec votre message. Lors de la réception, le webhook entrant inclura la signature et tous les champs dont vous avez besoin pour générer la signature dans votre application afin de vérifier que les deux signatures correspondent.

Vous utilisez une signature pour :

  • Verify that a request originates from a trusted source (Vérifier qu'une demande provient d'une source fiable)
  • S'assurer que le message n'a pas été altéré en cours de route
  • Défense contre l'interception et le rejeu ultérieur

Contenu

Ce document explique comment utiliser les signatures avec les messages, à la fois pour signer les messages que vous envoyez et pour vérifier que les messages entrants comportent une signature correcte.

Utiliser des signatures lors de l'envoi de messages

Pour envoyer un message avec une signature, vous devez utiliser la fonction SIGNATURE_SECRET au lieu de votre API_SECRET lors de l'envoi du message. Vous pouvez trouver le secret de signature et choisir l'algorithme de signature à utiliser en visitant la page tableau de bord. L'algorithme par défaut est le suivantHachure MD5et nous soutenons également MD5 HMAC, SHA1 HMAC, SHA-256 HMAC et SHA-512 HMAC.

Vonage vous recommande fortement d'utiliser l'un de nos services d'assistance technique. bibliothèques clients pour générer ou valider des signatures. Si vous ne peut faire cela pour une raison ou pour une autre, vous peut générer et valider les signatures vous-même, mais cela peut s'avérer compliqué et source d'erreurs. Il convient de se référer à la page d'accueil de la section sur la génération manuelle de signatures.

La procédure d'envoi d'un message signé est la suivante :

  1. Créer une signature demande pour envoyer un SMS.
  2. Vérifier le codes de réponse et vérifiez que vous avez envoyé la demande correctement.
  3. Votre message est remis au combiné. Le combiné de l'utilisateur renvoie un accusé de réception.
  4. (facultatif) Si vous avez demandé des accusés de réception et des messages entrants signés, vous devrez valider la signature pour chaque demande entrante.

Si vous n'avez pas généré la signature correctement, le statut est 14, invalid signature. Vous trouverez plus d'informations dans la rubrique dépannage de ce guide.

Par défaut, les signatures de messages sont facultatives lors de l'envoi de messages et ne sont pas incluses dans les webhooks entrants. Pour activer les webhooks signés ou imposer la signature de tous les messages envoyés, veuillez contacter soutien.

L'exemple de code ci-dessous montre comment envoyer un message signé avec l'API SMS.

Conditions préalables

npm install @vonage/server-sdk

Créez un fichier nommé send-signed-sms.js et ajoutez le code suivant :

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',
  },
});

Voir la source complète

Rédiger le code

Ajouter ce qui suit à 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();

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

node send-signed-sms.js

Conditions préalables

Ajouter ce qui suit à build.gradle:

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

Créez un fichier nommé SendSignedSms et ajoutez le code suivant à la méthode main:

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

Voir la source complète

Rédiger le code

Ajouter ce qui suit à la méthode main du fichier SendSignedSms:


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}")

Voir la source complète

Exécutez votre code

Nous pouvons utiliser le plugin application pour Gradle afin de simplifier l'exécution de notre application. Mettez à jour votre build.gradle avec ce qui suit :

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

Lancez la commande suivante gradle pour exécuter votre application, en remplaçant com.vonage.quickstart.kt.sms par le paquet contenant SendSignedSms:

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

Conditions préalables

Ajouter ce qui suit à build.gradle:

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

Créez un fichier nommé SendSignedSms et ajoutez le code suivant à la méthode 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;

Voir la source complète

Ajouter ce qui suit à la méthode main du fichier SendSignedSms:

);

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

Voir la source complète

Rédiger le code

Ajouter ce qui suit à la méthode main du fichier SendSignedSms:

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

Voir la source complète

Exécutez votre code

Nous pouvons utiliser le plugin application pour Gradle afin de simplifier l'exécution de notre application. Mettez à jour votre build.gradle avec ce qui suit :

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

Lancez la commande suivante gradle pour exécuter votre application, en remplaçant com.vonage.quickstart.sms par le paquet contenant SendSignedSms:

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

Conditions préalables

Install-Package Vonage

Créez un fichier nommé SendSignedSms.cs et ajoutez le code suivant :


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

Voir la source complète

Rédiger le code

Ajouter ce qui suit à 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"
});

Voir la source complète

Conditions préalables

composer require vonage/client

Rédiger le code

Ajouter ce qui suit à 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";

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

php send-signed-sms.php

Conditions préalables

pip install vonage python-dotenv

Rédiger le code

Ajouter ce qui suit à 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)

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

python sms/send-signed-sms.py

Valider la signature des messages entrants

Afin de vérifier l'origine des webhooks entrants vers votre point de terminaison SMS, vous pouvez activer la signature des messages entrants - contact soutien pour demander que les messages entrants soient accompagnés d'une signature. Si ce paramètre est activé, les webhooks pour les SMS entrants et les accusés de réception incluront une signature. sig paramètre. Utilisez les autres paramètres de la demande avec votre secret de signature pour générer la signature et la comparer à la signature envoyée. Si les deux correspondent, la demande est valide.

Contact soutien pour activer la signature des messages sur votre Account.

L'exemple de code ci-dessous montre comment vérifier une signature pour un message SMS entrant, à l'aide de la fonction sig dans la chaîne de requête.

Conditions préalables

npm install express @vonage/server-sdk

Rédiger le code

Ajouter ce qui suit à 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);

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

node verify-signed-sms.js

Conditions préalables

Ajouter ce qui suit à build.gradle:

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

Créez un fichier nommé ReceiveSignedSms et ajoutez le code suivant à la méthode main:

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

Voir la source complète

Rédiger le code

Ajouter ce qui suit à la méthode main du fichier ReceiveSignedSms:

     * 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);        
}

Voir la source complète

Exécutez votre code

Nous pouvons utiliser le plugin application pour Gradle afin de simplifier l'exécution de notre application. Mettez à jour votre build.gradle avec ce qui suit :

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

Lancez la commande suivante gradle pour exécuter votre application, en remplaçant com.vonage.quickstart.sms par le paquet contenant ReceiveSignedSms:

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

Conditions préalables

Install-Package Vonage

Créez un fichier nommé SmsController.cs et ajoutez le code suivant :

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

Voir la source complète

Rédiger le code

Ajouter ce qui suit à 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();
        }
    }
}

Voir la source complète

Conditions préalables

composer require vonage/client

Rédiger le code

Ajouter ce qui suit à 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');
}

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

php verify-signed-sms.php

Conditions préalables

pip install vonage python-dotenv fastapi[standard]

Rédiger le code

Ajouter ce qui suit à 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')

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

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

Note: A POST peut également inclure des données de type chaîne de requête. L'envoi des deux POST et les données de type chaîne de requête ne sont pas prises en charge par l'API SMS et les résultats peuvent être inattendus.

Générer manuellement une signature

Il est fortement recommandé que vous utilisiez la fonctionnalité existante de votre bibliothèque Vonage pour générer et valider les signatures. Si vous n'utilisez pas une bibliothèque dotée de cette fonctionnalité, vous devrez générer la signature vous-même. La technique est légèrement différente si vous générez une signature 'MD5 hash' ou une des signatures HMAC.

Étape 1 : Pour les signatures par hachage et HMAC

Si vous êtes la génération d'une signature : Ajouter l'horodatage actuel à la liste des paramètres avec la clé timestamp. Il s'agit d'un nombre entier contenant le nombre de secondes écoulées depuis l'époque (parfois également connu sous le nom de temps UNIX).

Si vous êtes validation d'une signature de Vonage : Retirer le sig avant de générer votre signature, et utilisez le paramètre timestamp fournie dans les paramètres de la demande.

Ensuite :

  • Boucle sur chacun des paramètres, triés par clé
  • Pour chaque valeur de la liste de paramètres, remplacer toutes les instances de & et = avec un trait de soulignement _.
  • Générer une chaîne composée de &akey=value&bkey=value. Notez qu'il y a une esperluette & au début de la chaîne !

À ce stade, le processus de MD5 et HMAC La technique de hachage utilisée sera différente. Suivez l'étape 2 ci-dessous pour décider de la technique de hachage à utiliser.

Étape 2

  • Hachure MD5

    1. Ajoutez la signature secrète à la fin de la chaîne, directement après la dernière valeur. Elle devrait maintenant ressembler à ceci : &akey=value&bkey=valueyour_signature_secret
    2. Faites maintenant passer la chaîne par une fonction de hachage md5 et convertissez les octets résultants en une chaîne de chiffres hexadécimaux. Il s'agit de votre signature de hachage MD5, qui doit être ajoutée aux paramètres HTTP de votre requête sous la forme de l'élément sig paramètre.
  • HMAC

    1. Créez un générateur HMAC avec l'algorithme de votre choix et le secret de votre signature comme clé.
    2. Passez maintenant la chaîne dans un générateur HMAC et convertissez les octets résultants en une chaîne de chiffres hexadécimaux. Il s'agit de votre signature HMAC, qui doit être ajoutée aux paramètres HTTP de votre requête sous la forme de l'élément sig (par exemple, pour PHP, cela ressemble à hash_hmac($algorithm, $data, $secret)).

Étape 3 : Notes supplémentaires

Gardez à l'esprit que même si vous avez modifié les valeurs des paramètres lors de la génération de la signature, les valeurs transmises en tant que paramètres HTTP doivent être les suivantes inchangé lors de l'envoi de ces paramètres à l'API SMS.

Dépannage des signatures

Voici quelques conseils et pièges à éviter lorsque l'on travaille avec des messages signés.

Consultez la réponse pour plus de détails

Si le message n'est pas envoyé comme prévu, vérifiez que la réponse ne contient pas de codes d'erreur qui ont été renvoyés. Cela vous donnera généralement plus de détails sur la marche à suivre.

Erreur 14 : Signature non valide

Si le texte envoyé contient des caractères spéciaux tels que & (esperluette) ou = (égaux), il faut les remplacer dans le texte utilisé pour créer la signature.

Pour ce faire, suivez les instructions suivantes :

  • Détecter que le texte comprend & ou =.
  • Créer une version du texte qui utilise _ (underscore) à la place de ces caractères spéciaux.
  • Utilisez la version assainie du texte pour créer la signature.

Le texte original peut toujours être envoyé/reçu, les remplacements de caractères ne sont nécessaires que pour générer la signature.