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.
- Enviar mensagens com assinaturas. Use o bibliotecas de cliente para gerar e enviar a mensagem assinada.
- Verificar as assinaturas nas mensagens recebidas para garantir a autenticidade da mensagem no webhook recebido.
- Gerar uma assinatura manualmente Caso não seja possível utilizar as bibliotecas existentes, o processo manual para geração de assinaturas está descrito aqui.
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:
- Criar um arquivo assinado solicitação para enviar um SMS.
- Verifique o códigos de resposta e certifique-se de que enviou a solicitação corretamente.
- Sua mensagem é entregue no aparelho. O aparelho do usuário envia um aviso de entrega.
- (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-sdkCrie 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',
},
});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();Execute seu código
Salve este arquivo no seu computador e execute-o:
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)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}")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`:
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;Adicione o seguinte ao método ` main ` do arquivo ` SendSignedSms `:
);
SmsSubmissionResponse response = client.getSmsClient().submitMessage(message);
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());
}
}
}
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`:
Pré-requisitos
Install-Package VonageCrie um arquivo chamado ` SendSignedSms.cs ` e insira o seguinte código:
var credentials = Credentials.FromApiKeySignatureSecretAndMethod(
vonageApiKey,
vonageApiSignatureSecret,
Vonage.Cryptography.SmsSignatureGenerator.Method.md5hash
);
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"
});Pré-requisitos
composer require vonage/clientEscreva 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";Execute seu código
Salve este arquivo no seu computador e execute-o:
Pré-requisitos
pip install vonage python-dotenvEscreva 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)Execute seu código
Salve este arquivo no seu computador e execute-o:
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-sdkEscreva 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);Execute seu código
Salve este arquivo no seu computador e execute-o:
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;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);
}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`:
Pré-requisitos
Install-Package VonageCrie um arquivo chamado ` SmsController.cs ` e insira o seguinte código:
{
[HttpGet("webhooks/inbound-sms")] 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();
}
}
}Pré-requisitos
composer require vonage/clientEscreva 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');
}Execute seu código
Salve este arquivo no seu computador e execute-o:
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')Execute seu código
Salve este arquivo no seu computador e execute-o:
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
- 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 - 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
sigparâmetro.
- Adicione o segredo de assinatura ao final da string, logo após o último valor. Agora, o resultado deve ficar mais ou menos assim:
-
HMAC
- Crie um gerador HMAC com o algoritmo de sua preferência e seu segredo de assinatura como chave.
- 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
sigparâ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.