Signierung von Requests

Als zusätzliche Sicherheit können Sie bei allen Anfragen an und von unserer API Signaturen verwenden. Die Verwendung von Signaturen ist optional. Wenn allerdings eine Signatur gesendet wird, muss diese valide sein.

Beim Senden von Anfragen an unsere API erzeugen Sie eine Signatur, die Sie mit Ihren Daten versenden. Beim Empfang enthält der eingehende Webhook die Signatur und alle Felder, die Sie zur Erstellung der Signatur in Ihrer Anwendung benötigen, um die Übereinstimmung der beiden Signaturen und damit die Richtigkeit des Webhooks zu überprüfen.

Mittels dieser Signatur kann sichergestellt werden, dass

  • der Request tatsächlich von der richtigen Quelle stammt,
  • der Request unterwegs nicht verfälscht wurde,
  • Requests nicht abgefangen und später wiederholt werden.

Die Signatur enthält dabei zwingend einige Daten wie unter anderem den Zeitstempel, die Ziel URL, einen sogenannten Nonce und die gesendeten Daten.


Aufbau der Signatur

Zur Erstellung einer Signatur werden folgende Daten benötigt:

WertBeschreibung
NonceEin zufälliger String, bestehend aus 32 alphanumerischen Zeichen. Dieser muss einzigartig für jeden Request sein.
ZeitstempelDer Zeitpunkt des Requests als Unix Timestamp, darf maximal 30 Sekunden zurückliegen
HTTP MethodeDie HTTP Request Methode, z.B. POST oder GET
Ziel URLDie vollständige URL, an die der Request gesendet wird
Content des RequestsMD5 Hash des Inhalts des Requests

Zur Generierung der Signatur wird der SHA256 HMAC Algorithmus mit dem Signierschlüssel Ihres Accounts verwendet. Den Schlüssel finden Sie in Ihrem Login im Bereich Entwickler in den API Einstellungen.


Struktur der zu signierenden Zeichenfolge

Folgendermaßen muss der zu signierende String aufgebaut werden:

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

Wenn Sie zum Beispiel diesen Request senden:

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

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

Wäre der zu signierende String wie folgt aufgebaut:

STRING_TO_SIGN =
  1634641200
  fpPRhAd1s8GXacfR39mWqKPynmmXfJnc
  POST
  https://gateway.seven.io/api/sms
  62dd06ffb3101dc2456517b177b744ae
WertErklärung
1634641200Der aktuelle Zeitstempel zum Zeitpunkt des Absendens des Requests, hier der 19.10.2021 um 13:00:00 Uhr
fpPRhAd1s8GXacfR39mWqKPynmmXfJncEin zufällig generierter String mit 32 Zeichen
POSTDie verwendete HTTP Methode
https://gateway.seven.io/api/smsDie Ziel URL
62dd06ffb3101dc2456517b177b744aeMD5( {"to": "49170123456789", "text": "Hello World! :-)", "from": "seven"} )

Erstellung der Signatur

Um nun die Signatur zu erstellen, verwenden Sie den SHA256 HMAC Algorithmus in Verbindung mit Signierschlüssel Ihres Accounts.

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

Ähnliche Implementierungen sind in den meisten gängigen Programmiersprachen gegeben, so zum Beispiel in PHP:

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

Senden der Signatur

Die Signatur, das Nonce und der Zeitstempel müssen in den HTTP Headern der Anfrage gesendet werden.

  • Name
    X-Signature
    Type
    string
    Description

    Die von Ihnen generierte Signatur

  • Name
    X-Timestamp
    Type
    integer
    Description

    Der Zeitstempel, zu dem die Signatur erstellt wurde

  • Name
    X-Nonce
    Type
    string
    Description

    Der von Ihnen erstelle Nonce


Beispiele

Bash Script mit curl und 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}\n${NONCE}\n${HTTP_VERB}\n${URL}\n${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}"

PHP Script

# 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 . "\n" .
  $nonce . "\n" .
  $http_verb . "\n" .
  $url . "\n" .
  md5($content_body);

$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;
Zuletzt aktualisiert: Vor 8 Monaten