Mensagens de assinatura

É possível usar assinaturas com a SMS API ao enviar e receber mensagens SMS. Ao enviar, você gera uma assinatura para enviar junto com sua mensagem. Ao receber, o webhook de entrada incluirá a assinatura e todos os campos necessários para que você gere a assinatura em seu aplicativo e verifique se as duas assinaturas coincidem.

Você usa uma assinatura para:

  • Verifique se uma solicitação provém de uma fonte confiável
  • Certifique-se de que a mensagem não tenha sido adulterada durante o trajeto
  • Proteger contra interceptação e reprodução posterior

Índice

Este documento explica como usar assinaturas em mensagens, tanto para assinar as mensagens que você envia quanto para verificar se as mensagens recebidas possuem uma assinatura válida.

Use assinaturas ao enviar mensagens

Para enviar uma mensagem com uma assinatura, você precisará usar o SIGNATURE_SECRET em vez do seu API_SECRET ao enviar a mensagem. Você pode encontrar o segredo de assinatura e escolher qual algoritmo de assinatura usar acessando o painel de controle. O algoritmo padrão é'Hash MD5' e também oferecemos suporte a MD5 HMAC, SHA1 HMAC, SHA-256 HMAC e SHA-512 HMAC.

A Vonage recomenda enfaticamente que você utilize um dos nossos bibliotecas de cliente para gerar ou validar assinaturas. Se você não consigo Se, por algum motivo, você fizer isso, você pode gerar e validar assinaturas por conta própria, mas isso pode ser complicado e suscetível a erros. Consulte o seção sobre a geração manual de assinaturas.

O processo para enviar uma mensagem assinada é o seguinte:

  1. Criar um arquivo assinado solicitação para enviar um SMS.
  2. Verifique o códigos de resposta e certifique-se de que enviou a solicitação corretamente.
  3. Sua mensagem é entregue no aparelho. O aparelho do usuário envia um aviso de entrega.
  4. (opcional) Se você solicitou recibos de entrega assinados e mensagens recebidas, convém validar a assinatura de cada solicitação recebida.

Se você não gerou a assinatura corretamente, o status é 14, invalid signature. Você pode encontrar mais informações no solução de problemas seção deste guia.

Por padrão, as assinaturas de mensagens são opcionais no envio de mensagens e não são incluídas nos webhooks recebidos. Para habilitar webhooks assinados ou exigir que todas as mensagens enviadas sejam assinadas, entre em contato com apoio.

O exemplo de código abaixo mostra como enviar uma mensagem assinada usando a SMS API.

Pré-requisitos

npm install @vonage/server-sdk

Crie um arquivo chamado ` send-signed-sms.js ` e insira o seguinte código:

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

Ver código-fonte completo

Escreva o código

Adicione o seguinte ao arquivo ` 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();

Ver código-fonte completo

Execute seu código

Salve este arquivo no seu computador e execute-o:

node send-signed-sms.js

Pré-requisitos

Adicione o seguinte ao arquivo ` build.gradle`:

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

Crie um arquivo chamado ` SendSignedSms ` e adicione o código a seguir ao método ` main `:

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

Ver código-fonte completo

Escreva o código

Adicione o seguinte ao método ` main ` do arquivo ` 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}")

Ver código-fonte completo

Execute seu código

Podemos usar o plugin “ aplicativo ” para o Gradle a fim de simplificar a execução do nosso aplicativo. Atualize seu arquivo ` build.gradle ` com o seguinte:

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

Execute o seguinte comando ` gradle ` para rodar seu aplicativo, substituindo ` com.vonage.quickstart.kt.sms ` pelo pacote que contém ` SendSignedSms`:

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

Pré-requisitos

Adicione o seguinte ao arquivo ` build.gradle`:

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

Crie um arquivo chamado ` SendSignedSms ` e adicione o código a seguir ao método ` 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;

Ver código-fonte completo

Adicione o seguinte ao método ` main ` do arquivo ` SendSignedSms `:

);

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

Ver código-fonte completo

Escreva o código

Adicione o seguinte ao método ` main ` do arquivo ` SendSignedSms `:

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

Ver código-fonte completo

Execute seu código

Podemos usar o plugin “ aplicativo ” para o Gradle a fim de simplificar a execução do nosso aplicativo. Atualize seu arquivo ` build.gradle ` com o seguinte:

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

Execute o seguinte comando ` gradle ` para rodar seu aplicativo, substituindo ` com.vonage.quickstart.sms ` pelo pacote que contém ` SendSignedSms`:

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

Pré-requisitos

Install-Package Vonage

Crie um arquivo chamado ` SendSignedSms.cs ` e insira o seguinte código:


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

Ver código-fonte completo

Escreva o código

Adicione o seguinte ao arquivo ` 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"
});

Ver código-fonte completo

Pré-requisitos

composer require vonage/client

Escreva o código

Adicione o seguinte ao arquivo ` 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";

Ver código-fonte completo

Execute seu código

Salve este arquivo no seu computador e execute-o:

php send-signed-sms.php

Pré-requisitos

pip install vonage python-dotenv

Escreva o código

Adicione o seguinte ao arquivo ` 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)

Ver código-fonte completo

Execute seu código

Salve este arquivo no seu computador e execute-o:

python sms/send-signed-sms.py

Validar a assinatura das mensagens recebidas

Para verificar a origem dos webhooks recebidos no seu endpoint de SMS, você pode ativar a assinatura de mensagens para as mensagens recebidas — entre em contato apoio para solicitar que as mensagens recebidas sejam acompanhadas de uma assinatura. Com essa configuração ativada, os webhooks tanto para SMS recebidas quanto para confirmações de entrega incluirão um sig parâmetro. Use os demais parâmetros da solicitação juntamente com seu segredo de assinatura para gerar a assinatura e compará-la com a assinatura que foi enviada. Se as duas coincidirem, a solicitação é válida.

Contato apoio para ativar a assinatura de mensagens no seu Account.

O exemplo de código abaixo mostra como verificar a assinatura de uma mensagem SMS recebida, utilizando o sig parâmetro na string de consulta.

Pré-requisitos

npm install express @vonage/server-sdk

Escreva o código

Adicione o seguinte ao arquivo ` 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);

Ver código-fonte completo

Execute seu código

Salve este arquivo no seu computador e execute-o:

node verify-signed-sms.js

Pré-requisitos

Adicione o seguinte ao arquivo ` build.gradle`:

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

Crie um arquivo chamado ` ReceiveSignedSms ` e adicione o código a seguir ao método ` main `:

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

Ver código-fonte completo

Escreva o código

Adicione o seguinte ao método ` main ` do arquivo ` 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);        
}

Ver código-fonte completo

Execute seu código

Podemos usar o plugin “ aplicativo ” para o Gradle a fim de simplificar a execução do nosso aplicativo. Atualize seu arquivo ` build.gradle ` com o seguinte:

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

Execute o seguinte comando ` gradle ` para rodar seu aplicativo, substituindo ` com.vonage.quickstart.sms ` pelo pacote que contém ` ReceiveSignedSms`:

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

Pré-requisitos

Install-Package Vonage

Crie um arquivo chamado ` SmsController.cs ` e insira o seguinte código:

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

Ver código-fonte completo

Escreva o código

Adicione o seguinte ao arquivo ` 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();
        }
    }
}

Ver código-fonte completo

Pré-requisitos

composer require vonage/client

Escreva o código

Adicione o seguinte ao arquivo ` 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');
}

Ver código-fonte completo

Execute seu código

Salve este arquivo no seu computador e execute-o:

php verify-signed-sms.php

Pré-requisitos

pip install vonage python-dotenv fastapi[standard]

Escreva o código

Adicione o seguinte ao arquivo ` 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')

Ver código-fonte completo

Execute seu código

Salve este arquivo no seu computador e execute-o:

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

Nota: A POST A solicitação também pode incluir dados da string de consulta. Ao enviar ambos POST Além disso, os dados da string de consulta não são suportados na SMS API, e os resultados podem ser inesperados.

Gerar uma assinatura manualmente

É altamente recomendado que você utilize a funcionalidade já existente na biblioteca da Vonage para gerar e validar assinaturas. Caso não esteja utilizando uma biblioteca com essa funcionalidade, você precisará gerar a assinatura por conta própria. A técnica é um pouco diferente se você estiver gerando uma assinatura do tipo “hash MD5” ou uma das assinaturas HMAC.

Passo 1: Tanto para assinaturas de hash quanto para assinaturas HMAC

Se você estiver gerando uma assinatura: Adicione o carimbo de data e hora atual à lista de parâmetros com a chave timestamp. Deve ser um número inteiro que represente o número de segundos desde a época (também conhecido, às vezes, como tempo UNIX)

Se você estiver validação de uma assinatura da Vonage: Remova o sig parâmetro antes de gerar sua assinatura e use o timestamp fornecidos nos parâmetros da solicitação.

Então:

  • Percorra cada um dos parâmetros, ordenados pela chave
  • Para cada valor na lista de parâmetros, substitua todas as ocorrências de & e = com um sublinhado _.
  • Gere uma sequência de caracteres composta por &akey=value&bkey=value. Observe que há um símbolo “&” & no início da sequência!

Nesta fase, o processo para MD5 e HMAC O resultado do hash será diferente. Siga a etapa 2 abaixo para decidir qual técnica de hash usar.

Etapa 2

  • Hash MD5

    1. Adicione o segredo de assinatura ao final da string, logo após o último valor. Agora, o resultado deve ficar mais ou menos assim: &akey=value&bkey=valueyour_signature_secret
    2. Agora, passe a string por uma função de hash MD5 e converta os bytes resultantes em uma sequência de dígitos hexadecimais. Essa é a sua assinatura de hash MD5, e deve ser adicionada aos parâmetros HTTP da sua solicitação como o sig parâmetro.
  • HMAC

    1. Crie um gerador HMAC com o algoritmo de sua preferência e seu segredo de assinatura como chave.
    2. Agora, passe a string por um gerador de HMAC e converta os bytes resultantes em uma string de dígitos hexadecimais. Essa é a sua assinatura HMAC e deve ser adicionada aos parâmetros HTTP da sua solicitação como o sig parâmetro (por exemplo, no PHP, fica assim: hash_hmac($algorithm, $data, $secret)).

Etapa 3: Observações adicionais

Lembre-se de que, embora você tenha alterado os valores dos parâmetros ao gerar a assinatura, os valores passados como parâmetros HTTP devem ser inalterado ao enviar esses parâmetros para a SMS API.

Solução de problemas relacionados a assinaturas

Aqui estão algumas dicas e armadilhas a serem observadas ao trabalhar com mensagens assinadas.

Confira a resposta para obter mais detalhes

Se a mensagem não for enviada conforme o esperado, verifique se há algum erro na resposta códigos de erro que foram retornados. Isso geralmente fornecerá mais detalhes sobre o que fazer a seguir.

Erro 14: Assinatura inválida

Se o texto que está sendo enviado incluir algum caractere especial, como & (e comercial) ou = (igual), então esses elementos precisam ser substituídos no texto usado para criar a assinatura.

Para isso, siga as instruções a seguir:

  • Detectar se o texto contém & ou =.
  • Crie uma versão do texto que utilize _ (traço de sublinhado) no lugar desses caracteres especiais.
  • Use a versão sanitizada do texto para criar a assinatura.

O texto original ainda pode ser enviado/recebido; as substituições de caracteres são necessárias apenas para gerar a assinatura.