Assinatura de Requisições

Como segurança adicional, você pode usar assinaturas em todas as solicitações para e da nossa API. O uso de assinaturas é opcional. No entanto, se uma assinatura for enviada, ela deve ser válida.

Ao enviar solicitações para nossa API, você gera uma assinatura que envia com seus dados. Ao receber, o webhook de entrada contém a assinatura e todos os campos que você precisa para criar a assinatura em sua aplicação, a fim de verificar a correspondência das duas assinaturas e, assim, a precisão do webhook.

Com esta assinatura, pode-se garantir que

  • a solicitação realmente vem da fonte correta,
  • a solicitação não foi alterada durante o trânsito,
  • as solicitações não sejam interceptadas e repetidas posteriormente.

A assinatura deve conter obrigatoriamente alguns dados, como o timestamp, a URL de destino, um chamado Nonce e os dados enviados.


Estrutura da Assinatura

Para criar uma assinatura, são necessários os seguintes dados:

ValorDescrição
NonceUma string aleatória, composta por 32 caracteres alfanuméricos. Deve ser única para cada solicitação.
TimestampO momento da solicitação como Unix Timestamp, não deve ter mais de 30 segundos
Método HTTPO método de solicitação HTTP, por exemplo, POST ou GET
URL de DestinoA URL completa para a qual a solicitação será enviada
Conteúdo da SolicitaçãoHash MD5 do conteúdo da solicitação

Para gerar a assinatura, é utilizado o algoritmo SHA256 HMAC com a chave de assinatura da sua conta. Pode encontrar a chave no seu login, na área Desenvolvedores, nas configurações da API.


Estrutura da sequência de caracteres a ser assinada

A sequência de caracteres a ser assinada deve ser construída da seguinte forma:

STRING_TO_SIGN =
  carimbo de data/hora + \n +
  Nonce + \n +
  Método HTTP + \n +
  URL de destino + \n +
  ContentBodyMD5

Se você enviar, por exemplo, esta requisição:

POST https://gateway.seven.io/api/sms

{"to": "49170123456789", "text": "Olá, mundo! :-)", "from": "seven"}

A sequência de caracteres a ser assinada seria construída da seguinte forma:

STRING_TO_SIGN =
  1634641200
  fpPRhAd1s8GXacfR39mWqKPynmmXfJnc
  POST
  https://gateway.seven.io/api/sms
  62dd06ffb3101dc2456517b177b744ae
ValorExplicação
1634641200O timestamp atual no momento do envio da requisição, aqui 19.10.2021 às 13:00:00
fpPRhAd1s8GXacfR39mWqKPynmmXfJncUma string gerada aleatoriamente com 32 caracteres
POSTO método HTTP utilizado
https://gateway.seven.io/api/smsA URL de destino
62dd06ffb3101dc2456517b177b744aeMD5( {"to": "49170123456789", "text": "Olá, mundo! :-)", "from": "seven"} )

Criação da assinatura

Para criar a assinatura, utilize o algoritmo SHA256 HMAC em conjunto com o chave de assinatura do seu account.

printf "${STRING_TO_SIGN}" | openssl dgst -sha256 -hmac "${SIGNING_SECRET}"

Implementações semelhantes estão disponíveis na maioria das linguagens de programação comuns, como por exemplo em PHP:

$signature = hash_hmac('sha256', $STRING_TO_SIGN, $SIGNING_SECRET);

Envio da Assinatura

A assinatura, o nonce e o timestamp devem ser enviados nos cabeçalhos HTTP da solicitação.

  • Name
    X-Signature
    Type
    string
    Description

    A assinatura gerada por você

  • Name
    X-Timestamp
    Type
    integer
    Description

    O timestamp no qual a assinatura foi criada

  • Name
    X-Nonce
    Type
    string
    Description

    O nonce criado por você


Exemplos

Script Bash com curl e openssl

#!/bin/bash

# Os seus dados API
API_KEY="SUA_CHAVE_API"
SIGNING_SECRET="SUA_CHAVE_DE_SINAIS"

# Criar um nonce aleatório
NONCE=$(openssl rand -hex 32)

# carimbo de data/hora
TIMESTAMP=$(date +%s)

# Daten des Requests
HTTP_VERB="POST"
URL="https://gateway.seven.io/api/sms"
CONTENT_BODY="{ \"to\": \"0170123456789\", \"text\": \"Olá, mundo! :-)\", \"from\": \"seven.io\" }"

# Criar assinatura
CONTENT_BODY_MD5=$(printf "${CONTENT_BODY}" | md5sum | awk '{print $1}')
STRING_TO_SIGN=$(printf "${TIMESTAMP}
${NONCE}
${HTTP_VERB}
${URL}
${CONTENT_BODY_MD5}")
SIGNATURE=$(printf "${STRING_TO_SIGN}" | openssl dgst -sha256 -hmac "${SIGNING_SECRET}" | sed 's/^.*= //')

# Enviar pedido
curl -X $HTTP_VERB $URL \
  -H "X-Api-Key: $API_KEY" \
  -H "X-Nonce: $NONCE" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "X-Signature: $SIGNATURE" \
  -H "Content-type: application/json" \
  -H "Accept: application/json" \
  -d "${CONTENT_BODY}"

Script PHP

# Os seus dados API
$key = 'SUA_CHAVE_API';
$secret = 'SUA_CHAVE_DE_SINAIS';

# Criar um nonce aleatório
$nonce = bin2hex(random_bytes(16));

# carimbo de data/hora
$timestamp = time();

# Dados da solicitação
$http_verb = 'POST';

$content_body = json_encode([
  'to' => '49170123456789',
  'text' => 'Olá, mundo! :-)',
  'from' => 'seven.io',
]);

$url = 'https://gateway.seven.io/api/sms';

# Criar assinatura
$StringToSign = [$timestamp, $nonce, $http_verb, $url, md5($content_body)];
$StringToSign = implode(PHP_EOL, $StringToSign);

$hash = hash_hmac('sha256', $StringToSign, $secret);

# Definir cabeçalho
$headers = [
  'X-Signature: ' . $hash,
  'X-Api-Key: ' . $key,
  'X-Timestamp:' . $timestamp,
  'X-Nonce:' . $nonce,
  'Content-type: application/json',
  'Accept: application/json'
];

# Enviar pedido
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content_body);

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

echo $result;