Signature des requêtes

Pour une sécurité supplémentaire, vous pouvez utiliser des signatures pour toutes les requêtes vers et depuis notre API. L'utilisation de signatures est optionnelle. Cependant, si une signature est envoyée, elle doit être valide.

Lors de l'envoi de requêtes vers notre API, vous générez une signature que vous envoyez avec vos données. À la réception, le webhook entrant contient la signature et tous les champs dont vous avez besoin pour créer la signature dans votre application afin de vérifier que les deux signatures correspondent et que le webhook est donc correct.

Cette signature peut être utilisée pour s'assurer que

  • la requête provient effectivement de la bonne source,
  • la requête n'a pas été falsifiée en cours de route,
  • les requêtes ne sont pas interceptées et répétées plus tard.

La signature doit contenir certaines données telles que l'horodatage, l'URL cible, un nonce et les données envoyées.


Structure de la signature

Les données suivantes sont nécessaires pour créer une signature :

valeurdescription
NonceUne chaîne aléatoire composée de 32 caractères alphanumériques. Elle doit être unique pour chaque requête.
HorodatageL'heure de la requête sous forme d'horodatage Unix, ne doit pas dater de plus de 30 secondes
Méthode HTTPLa méthode de requête HTTP, par exemple POST ou GET
URL cibleL'URL complète à laquelle la requête est envoyée
Contenu de la requêteHash MD5 du contenu de la requête

Pour générer la signature, l'algorithme SHA256 HMAC est utilisé avec la clé de signature de votre compte. Vous pouvez trouver la clé dans votre connexion dans la zone Développeur dans les paramètres API.


Structure de la chaîne de caractères à signer

La chaîne à signer doit être structurée comme suit :

STRING_TO_SIGN =
  Horodatage + \n +
  Nonce + \n +
  Méthode HTTP + \n +
  URL_Cible + \n +
  ContentBodyMD5

Par exemple, si vous envoyez cette requête :

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

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

La chaîne à signer serait structurée comme suit :

STRING_TO_SIGN =
  1634641200
  fpPRhAd1s8GXacfR39mWqKPynmmXfJnc
  POST
  https://gateway.seven.io/api/sms
  62dd06ffb3101dc2456517b177b744ae
valeurexplication
1634641200L'horodatage actuel au moment où la requête a été envoyée, ici le 19.10.2021 à 13:00:00
fpPRhAd1s8GXacfR39mWqKPynmmXfJncUne chaîne générée aléatoirement avec 32 caractères
POSTLa méthode HTTP utilisée
https://gateway.seven.io/api/smsL'URL de destination
62dd06ffb3101dc2456517b177b744aeMD5( {"to": "49170123456789", "text": "Hello World! :-)", "from": "seven"} )

Création de la signature

Pour créer la signature, utilisez l'algorithme SHA256 HMAC en conjonction avec la clé de signature de votre compte.

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

Des implémentations similaires sont disponibles dans la plupart des langages de programmation courants, comme PHP :

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

Envoi de la signature

La signature, le nonce et l'horodatage doivent être envoyés dans les en-têtes HTTP de la requête.

  • Name
    X-Signature
    Type
    string
    Description

    La signature générée par vous

  • Name
    X-Timestamp
    Type
    integer
    Description

    L'horodatage auquel la signature a été créée

  • Name
    X-Nonce
    Type
    string
    Description

    Le nonce que vous avez créé


Exemples

Script Bash avec curl et openssl

#!/bin/bash

# Vos données API
API_KEY="VOTRE_CLÉ_API"
SIGNING_SECRET="VOTRE_CLE_SIGNATURE"

# Créer un nonce aléatoire
NONCE=$(openssl rand -hex 32)

# Horodatage
TIMESTAMP=$(date +%s)

# Données de la requête
HTTP_VERB="POST"
URL="https://gateway.seven.io/api/sms"
CONTENT_BODY="{ \"to\": \"0170123456789\", \"text\": \"Hello World! :-)\", \"from\": \"seven.io\" }"

# Créer la signature
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/^.*= //')

# Envoyer la requête
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

# Vos données API
$key = 'VOTRE_CLÉ_API';
$secret = 'VOTRE_CLE_SIGNATURE';

# Créer un nonce aléatoire 
$nonce = bin2hex(random_bytes(16)); 

# Horodatage
$timestamp = time();

# Données de la requête
$http_verb = 'POST';

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

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

# Créer la signature
$StringToSign = [$timestamp, $nonce, $http_verb, $url, md5($content_body)];
$StringToSign = implode(PHP_EOL, $StringToSign);

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

# Définir les en-têtes
$headers = [
  'X-Signature: ' . $hash,
  'X-Api-Key: ' . $key,
  'X-Timestamp:' . $timestamp,
  'X-Nonce:' . $nonce,
  'Content-type: application/json',
  'Accept: application/json'
];

# Envoyer la requête
$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;