Firmado de Solicitudes

Como seguridad adicional, puede utilizar firmas en todas las solicitudes hacia y desde nuestra API. El uso de firmas es opcional. Sin embargo, si se envía una firma, esta debe ser válida.

Al enviar solicitudes a nuestra API, genere una firma que envíe junto con sus datos. Al recibir, el webhook entrante contiene la firma y todos los campos que necesita para crear la firma en su aplicación, para verificar la coincidencia de ambas firmas y, por lo tanto, la exactitud del webhook.

Mediante esta firma se puede asegurar que

  • la solicitud realmente proviene de la fuente correcta,
  • la solicitud no ha sido alterada en tránsito,
  • las solicitudes no sean interceptadas y repetidas más tarde.

La firma contiene necesariamente algunos datos como, entre otros, la marca de tiempo, la URL de destino, un llamado Nonce y los datos enviados.


Estructura de la Firma

Para crear una firma se necesitan los siguientes datos:

ValorDescripción
NonceUna cadena aleatoria, compuesta por 32 caracteres alfanuméricos. Debe ser única para cada solicitud.
Marca de tiempoEl momento de la solicitud como un Timestamp Unix, no debe ser mayor a 30 segundos de antigüedad
Método HTTPEl método de solicitud HTTP, por ejemplo, POST o GET
URL de destinoLa URL completa a la que se envía la solicitud
Contenido de la solicitudHash MD5 del contenido de la solicitud

Para la generación de la firma se utiliza el algoritmo SHA256 HMAC con la clave de firma de su cuenta. Puede encontrar la clave en su inicio de sesión en la sección Desarrollador en la configuración de la API.


Estructura de la cadena de caracteres a firmar

La cadena a firmar debe estructurarse de la siguiente manera:

STRING_TO_SIGN =
  Zeitstempel + \n +
  Nonce + \n +
  HTTPMethode + \n +
  ZielURL + \n +
  ContentBodyMD5

Por ejemplo, si envía esta solicitud:

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

{"to": "49170123456789", "text": "Hello World! :-)", "from": "seven"}

La cadena a firmar se estructuraría de la siguiente manera:

STRING_TO_SIGN =
  1634641200
  fpPRhAd1s8GXacfR39mWqKPynmmXfJnc
  POST
  https://gateway.seven.io/api/sms
  62dd06ffb3101dc2456517b177b744ae
ValorExplicación
1634641200La marca de tiempo actual en el momento de enviar la solicitud, aquí el 19.10.2021 a las 13:00:00
fpPRhAd1s8GXacfR39mWqKPynmmXfJncUna cadena generada aleatoriamente con 32 caracteres
POSTEl método HTTP utilizado
https://gateway.seven.io/api/smsLa URL de destino
62dd06ffb3101dc2456517b177b744aeMD5( {"to": "49170123456789", "text": "Hello World! :-)", "from": "seven"} )

Creación de la firma

Para crear la firma, utilice el algoritmo SHA256 HMAC junto con la clave de firma de su cuenta.

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

Implementaciones similares están disponibles en la mayoría de los lenguajes de programación comunes, por ejemplo, en PHP:

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

Envío de la firma

La firma, el nonce y la marca de tiempo deben enviarse en los encabezados HTTP de la solicitud.

  • Name
    X-Signature
    Type
    string
    Description

    La firma generada por usted

  • Name
    X-Timestamp
    Type
    integer
    Description

    La marca de tiempo en la que se creó la firma

  • Name
    X-Nonce
    Type
    string
    Description

    El nonce creado por usted


Ejemplos

Script de Bash con curl y openssl

#!/bin/bash

# Ihre API Daten
API_KEY="IHR_API_SCHLÜSSEL"
SIGNING_SECRET="IHR_SIGNIER_SCHLÜSSEL"

# Zufälligen Nonce erstellen
NONCE=$(openssl rand -hex 32)

# Zeitstempel
TIMESTAMP=$(date +%s)

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

# Signatur erstellen
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/^.*= //')

# Request absenden
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 de PHP

# Ihre API Daten
$key = 'IHR_API_SCHLÜSSEL';
$secret = 'IHR_SIGNIER_SCHLÜSSEL';

# Zufälligen Nonce erstellen 
$nonce = bin2hex(random_bytes(16)); 

# Zeitstempel
$timestamp = time();

# Daten des Requests
$http_verb = 'POST';

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

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

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

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

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

# Request absenden
$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;