Signing of requests
For additional security, you can use signatures for all requests to and from our API. The use of signatures is optional. However, if a signature is sent, it must be valid.
When sending requests to our API, you generate a signature that you send with your data. On receipt, the incoming webhook contains the signature and all the fields you need to create the signature in your application in order to check that the two signatures match and that the webhook is therefore correct.
This signature can be used to ensure that
- the request actually comes from the correct source,
- the request has not been falsified en route,
- requests are not intercepted and repeated later.
The signature must contain certain data such as the timestamp, the target URL, a nonce and the data sent.
Structure of the signature
The following data is required to create a signature:
value | description |
---|---|
Nonce | A random string consisting of 32 alphanumeric characters. This must be unique for each request. |
Timestamp | The time of the request as a Unix timestamp, must not be more than 30 seconds in the past |
HTTP method | The HTTP request method, e.g. POST or GET |
Target URL | The complete URL to which the request is sent |
Content of the request | MD5 hash of the content of the request |
To generate the signature, the SHA256 HMAC algorithm is used with the signing key of your account. You can find the key in your login in the Developer area in the API settings.
Structure of the character string to be signed
The string to be signed must be structured as follows:
STRING_TO_SIGN =
Timestamp + \n +
Nonce + \n +
HTTP method + \n +
TargetURL + \n +
ContentBodyMD5
For example, if you send this request:
POST https://gateway.seven.io/api/sms
{"to": "49170123456789", "text": "Hello World! :-)", "from": "seven"}
The string to be signed would be structured as follows:
STRING_TO_SIGN =
1634641200
fpPRhAd1s8GXacfR39mWqKPynmmXfJnc
POST
https://gateway.seven.io/api/sms
62dd06ffb3101dc2456517b177b744ae
value | explanation |
---|---|
1634641200 | The current timestamp at the time the request was sent, here 19.10.2021 at 13:00:00 |
fpPRhAd1s8GXacfR39mWqKPynmmXfJnc | A randomly generated string with 32 characters |
POST | The HTTP method used |
https://gateway.seven.io/api/sms | The destination URL |
62dd06ffb3101dc2456517b177b744ae | MD5( {"to": "49170123456789", "text": "Hello World! :-)", "from": "seven"} ) |
Creation of the signature
To create the signature, use the SHA256 HMAC algorithm in conjunction with the signing key of your account.
printf "${STRING_TO_SIGN}" | openssl dgst -sha256 -hmac "${SIGNING_SECRET}"
Similar implementations are available in most common programming languages, such as PHP:
$signature = hash_hmac('sha256', $STRING_TO_SIGN, $SIGNING_SECRET);
Sending the signature
The signature, the nonce and the timestamp must be sent in the HTTP headers of the request.
- Name
X-Signature
- Type
- string
- Description
The signature generated by you
- Name
X-Timestamp
- Type
- integer
- Description
The timestamp at which the signature was created
- Name
X-Nonce
- Type
- string
- Description
The nonce you created
Examples
Bash Script with curl and openssl
#!/bin/bash
# Your API data
API_KEY="YOUR_API_KEY"
SIGNING_SECRET="YOUR_SIGNING_KEY"
# Create a random nonce
NONCE=$(openssl rand -hex 32)
# Timestamp
TIMESTAMP=$(date +%s)
# Data of the request
HTTP_VERB="POST"
URL="https://gateway.seven.io/api/sms"
CONTENT_BODY="{ \"to\": \"0170123456789\", \"text\": \"Hello World! :-)\", \"from\": \"seven.io\" }"
# Create signature
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/^.*= //')
# Send request
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
# Your API data
$key = 'YOUR_API_KEY';
$secret = 'YOUR_SIGN_KEY';
# Create a random nonce
$nonce = bin2hex(random_bytes(16));
# Timestamp
$timestamp = time();
# Data of the request
$http_verb = 'POST';
$content_body = json_encode([
'to' => '49170123456789',
'text' => 'Hello World! :-)',
'from' => 'seven.io',
]);
$url = 'https://gateway.seven.io/api/sms';
# Create signature
$StringToSign = $timestamp . "\n" .
$nonce . "\n" .
$http_verb . "\n" .
$url . "\n" .
md5($content_body);
$hash = hash_hmac('sha256', $StringToSign, $secret);
# Set header
$headers = [
'X-Signature: ' . $hash,
'X-Api-Key: ' . $key,
'X-Timestamp:' . $timestamp,
'X-Nonce:' . $nonce,
'Content-type: application/json',
'Accept: application/json'
];
# Send request
$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;