Auth & Security
2.1 Authentication
Beginning from v1, all API calls require Authentication. The service uses HTTP signature based authentication.
This means to successfully authenticate with the APIs you must provide a valid signature to your request.
This consists in adding an element to the header of the request:
| Header | Description |
|---|---|
X-SIGNATURE | The signature header of the request |
See section 4.1 for information about how to create a valid signature.
2.2 HTTPS
All API calls have to be made through a secure https connection.
4. Security
4.1 Authentication
Digital signatures can ensure the reliability and anti-repudiation of the API data transmitted.
Each shop is assigned a shopId by Kenz'up.
Each client can then provide a list of terminalId they intend to use.
The API access is authenticated against the shopId and terminalId by the RSA signature.
Client and Kenz'up must exchange RSA keys before making API calls, and the length of RSA key must be at least 2048 bits, but we recommend to use a 3072 bits key. When making API call to Kenz'up, client uses the RSA private key to sign the API request. After receiving the API request, Kenz'up will use the client’s RSA public key to verify whether the signature is matched to the content of API request. Similarly, when client receives the API response, it is highly recommended that client verifies the signature of API response by using Kenz'up’s RSA public key.
Here is an overview of how the signing process works:

4.2 Signing the request
To sign a request it is necessary to add a specific content to the X-SIGNATURE header.
The content looks something like this (line-breaks are added for readability, but should not be included):
client_id=POS_123456789,
host=kenzup.com,
method=POST,
timestamp=2020-02-12T19:20:30+01:00,
uri=/api/v1/shops/1234/earn-requests, payload=eyJhbW91bnQiOiAxMi40NSwgImN1cnJlbmN5IjogIk1BRCIsICJvcmRlcl9pZCI6ICJUWF8xMjM0NTY3ODkiLCAidGVybWluYWxfaWQiOiAiUE9TXzEyMzQ1Njc4OSIsICJ0aW1lIjogIjIwMjAtMDItMTJUMTk6MjA6MzArMDE6MDAifQ==,
signature=bc8mNftoUqwgBi1TepFxwk4KtzBa/Y3vgnPKYZd1ZkxU/Fa9He3suRtKMlvL3woXChegLo46A50nMk1mAqC5dZq0D9OPRdm8aY+3855fSoMCT2e6JYxOCZT7OtVj3czDj6bn3rNLKWkr+zPP+pAd55Atiu1udBf163SBcc6hP7M=
4.3 Creating the X-SIGNATURE content
The content is generate starting from a canonical message with this format:
"client_id={client_id}, host={host}, method={method}, payload={payload_digest}, timestamp={timestamp}, uri={uri}"
| Parameter | Description |
|---|---|
client_id | This represent the client/terminal id of the key used to sign the request |
host | The host the request is made to (e.g. kenzup.com, staging-app.kenzup.com) |
method | The method of the request (GET, POST, PUT, etc.). It must be uppercase. |
payload | The Base64 representation of the request payload converted to JSON format (see section 4.4 for more details). If the request has no payload, this should be the Base64 representation of an empty payload base64({}) |
timestamp | Timestamp of the request. Must include Timezone. |
uri | The uri of the request (e.g. /api/v1/shops/1234/earn-requests) |
Here is an example of how the signature would be generated for an Earn-only request.
Assuming this scenario:
Request: POST /api/v1/shops/1234/earn-requests
Params:
{
"terminal_id": "POS_123456789",
"amount": 12.45,
"currency": "MAD",
"order_id": "TX_123456789",
"time": "2020-02-12T19:20:30+01:00"
}
1. Create the canonical message
canonical_message = "client_id=POS_123456789, host=kenzup.com, method=POST, timestamp=2020-02-12T19:20:30+01:00, uri=/api/v1/shops/1234/earn-requests"
2. Create the Base64 representation of the payload with keys sorted alphabetically
base64_payload = base64({"amount": 12.45, "currency": "MAD", "order_id": "TX_123456789", "terminal_id": "POS_123456789", "time": "2020-02-12T19:20:30+01:00"})
3. Add the encoded payload to the canonical message
canonical_message = "client_id=POS_123456789, host=kenzup.com, method=POST, timestamp=2020-02-12T19:20:30+01:00, uri=/api/v1/shops/1234/earn-requests, payload=eyJhbW91bnQiOiAxMi40NSwgImN1cnJlbmN5IjogIk1BRCIsICJvcmRlcl9pZCI6ICJUWF8xMjM0NTY3ODkiLCAidGVybWluYWxfaWQiOiAiUE9TXzEyMzQ1Njc4OSIsICJ0aW1lIjogIjIwMjAtMDItMTJUMTk6MjA6MzArMDE6MDAifQ=="
4. Hash the canonical message using a SHA256 algorithm and sign it using your RSA private key using PKCS#1 v1.5 encryption.
digest = SHA256.new()
digest.update(canonical_message)
signer = PKCS1_v1_5.new(private_key)
signature = signer.sign(digest)
5. Base64-encode the signature
The result should be something like this:
jz57y8wC9RFjXwOqRwOGs0Wp7ehEkWggyJ8KQ/wMGvU5p85HkfYGJtM6VY4zfFgG39zlb8qKNzTEopi4WrsIKP5UNzgwdXYztiFaJuEwcjy4wHe6Q6sE0eG43gYk+xOO+ZBSqxEHOM5j/rm6Dxt5EiDvhdJPd88vYsNY5q8YvjM=
6. Add the signature to the canonical message to create the header signature. The signature element must be the last one.
header_signature = "client_id=POS_123456789, host=kenzup.com, method=POST, timestamp=2020-02-12T19:20:30+01:00, uri=/api/v1/shops/1234/earn-requests, payload=eyJhbW91bnQiOiAxMi40NSwgImN1cnJlbmN5IjogIk1BRCIsICJvcmRlcl9pZCI6ICJUWF8xMjM0NTY3ODkiLCAidGVybWluYWxfaWQiOiAiUE9TXzEyMzQ1Njc4OSIsICJ0aW1lIjogIjIwMjAtMDItMTJUMTk6MjA6MzArMDE6MDAifQ==, signature=jz57y8wC9RFjXwOqRwOGs0Wp7ehEkWggyJ8KQ/wMGvU5p85HkfYGJtM6VY4zfFgG39zlb8qKNzTEopi4WrsIKP5UNzgwdXYztiFaJuEwcjy4wHe6Q6sE0eG43gYk+xOO+ZBSqxEHOM5j/rm6Dxt5EiDvhdJPd88vYsNY5q8YvjM="
7. Add X-SIGNATURE: <header_signature> to the header
4.4 Hashing the payload
The APIs require payload to be included into the signtature evaluation to guarantee it has not been tempered on transit.
To allow the server to validate it, the payload must be converted into a JSON representation and then encoded into Base64 format.
The format before hashing must be a valid JSON.
// CORRECT
{"amount": 160, "currency": "MAD", "order_id": "1588675781", "terminal_id": "Terminal_001", "time": "2020-05-05T10:49:41+00:00"}
// CORRECT
{"amount":160,"currency":"MAD","order_id":"1588675781","terminal_id":"Terminal_001","time":"2020-05-05T10:49:41+00:00"}
// WRONG: JSON requires double-quotes
{'amount': 160, 'currency': 'MAD', 'order_id': '1588675781', 'terminal_id': 'Terminal_001', 'time': '2020-05-05T10:49:41+00:00'}
4.5 Error codes for signature
| Error Code | Description |
|---|---|
SignatureAuthenticationFailed | Missing or malformed X-SIGNATURE header |
MissingSignatureException | Missing X-SIGNATURE header |
MissingHttpSignatureParamException | One or more params missing from X-SIGNATURE header |
BadHttpSignatureParamException | One or more values missing from X-SIGNATURE header |
BadHttpSignatureUriException | uri not equal to request path |
BadHttpSignatureHostException | host not equal to request host |
BadHttpSignatureMethodException | method not equal to request method |
BadHttpSignaturePayloadException | payload hash not equal to request params hash |
BadHttpSignatureTimestampException | timestamp is wrong. This can happen in three scenarios:- timestamp is in the future - timestamp is more than 5 minutes in the past - timestamp does not include timezone |
4.6 Signing example
This is an example of how the signature can be created using multiple scripring forms:
1. Python
import json
from datetime import datetime, timezone
from base64 import b64decode, b64encode
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
import pytz
import uuid
def create_signature(uri, payload, method, client_id, host, timestamp, private_key):
json_payload = json.dumps(payload, sort_keys=True)
b64_payload = b64encode(json_payload.encode('utf-8')).decode()
#print(b64_payload)
message = 'client_id={}, host={}, method={}, payload={}, timestamp={}, uri={}'.format(
client_id,
host,
method,
b64_payload,
timestamp,
uri
)
private_key = RSA.importKey(private_key)
digest = SHA256.new()
digest.update(message.encode('utf-8'))
signer = PKCS1_v1_5.new(private_key)
signature = b64encode(signer.sign(digest)).decode()
return signature, b64_payload
# return f'{message}, signature={signature}'
def create_signature_from_message(message, private_key):
private_key = RSA.importKey(private_key)
digest = SHA256.new()
digest.update(message.encode('utf-8'))
signer = PKCS1_v1_5.new(private_key)
signature = b64encode(signer.sign(digest)).decode()
return signature
def verify_sign(public_key, signature, data):
rsakey = RSA.importKey(public_key)
signer = PKCS1_v1_5.new(rsakey)
digest = SHA256.new()
digest.update(data.encode('utf-8'))
if signer.verify(digest, b64decode(signature)):
return True
return False
EST = pytz.timezone('Africa/Casablanca')
date_time = datetime.now(EST)
private_key = '-----BEGIN RSA PRIVATE KEY-----\nMIIE\n-----END RSA PRIVATE KEY-----'
uri = '/api/v1/shops/f09fbdb6-3245-4f2b-a928-23669a0b93a3/earn-requests'
method = 'POST'
host = 'staging-app.kenzup.com'
client_id = 'renault-staging-shop'
timestamp = date_time.strftime("%Y-%m-%dT%H:%M:%S%z")
order_id = str(uuid.uuid1())
terminal_id = str(uuid.uuid4())
data = {'agent_id':None, 'agent_mobilenumber':None, 'agent_name':None, 'amount':1.0, 'currency':'MAD', 'customer':None, 'force':False, 'order_id':order_id, 'terminal_id':terminal_id , 'time':timestamp}
data_to_show = '{\\"agent_id\\":null, \\"agent_mobilenumber\\":null, \\"agent_name\\":null, \\"amount\\":1.0, \\"currency\\":\\"MAD\\", \\"customer\\":null, \\"force\\":false, \\"order_id\\":\\"'+order_id+'\\", \\"terminal_id\\":\\"'+terminal_id+'\\", \\"time\\":\\"'+timestamp+'\\"}'
signature, payload = create_signature(uri=uri, payload=data, method=method, host=host, client_id=client_id, timestamp=timestamp, private_key=private_key)
message='client_id='+client_id+', host='+host+', method='+method+', payload='+payload+', timestamp='+timestamp+', uri='+uri
print ('curl --request "'+method+'" --url "https://'+host+uri+'" --header "content-type: application/json" --header "X-SIGNATURE: '+message+', signature='+signature+'" --data "'+data_to_show+'"')
2. Java
import java.util.Base64;
import java.util.UUID;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.signers.PSSSigner;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
public class SignatureGenerator {
static {
Security.addProvider(new BouncyCastleProvider());
}
public static void main(String[] args) {
String uri = "/api/v1/shops/f09fbdb6-3245-4f2b-a928-23669a0b93a3/earn-requests";
String method = "POST";
String host = "staging-app.kenzup.com";
String client_id = "renault-staging-shop";
String private_key = "-----BEGIN RSA PRIVATE KEY-----\nMIIE\n-----END RSA PRIVATE KEY-----";
ObjectMapper mapper = new ObjectMapper();
UUID order_id = UUID.randomUUID();
UUID terminal_id = UUID.randomUUID();
ZonedDateTime timestamp = ZonedDateTime.now(ZoneId.of("Africa/Casablanca"));
String data_to_show = "{\"agent_id\":null, \"agent_mobilenumber\":null, \"agent_name\":null, \"amount\":1.0, \"currency\":\"MAD\", \"customer\":null, \"force\":false, \"order_id\":\"" + order_id.toString() + "\", \"terminal_id\":\"" + terminal_id.toString() + "\", \"time\":\"" + timestamp.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX")) + "\"}";
try {
ObjectWriter writer = mapper.writer().with(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
String payload = Base64.getEncoder().encodeToString(writer.writeValueAsString(data).getBytes("UTF-8"));
String message = String.format("client_id=%s, host=%s, method=%s, payload=%s, timestamp=%s, uri=%s",
client_id, host, method, payload, timestamp.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX")), uri);
PemReader pemReader = new PemReader(new StringReader(private_key));
PemObject pemObject = pemReader.readPemObject();
byte[] privateKeyBytes = pemObject.getContent();
pemReader.close();
PSSSigner signer = new PSSSigner(new SHA256Digest());
signer.init(true, new RSAKeyParameters(true, new BigInteger(1, privateKeyBytes), new BigInteger(1, pemObject.getContent())));
signer.update(message.getBytes("UTF-8"));
byte[] signatureBytes = signer.generateSignature();
String signature = Base64.getEncoder().encodeToString(signatureBytes);
System.out.println(String.format("curl --request \"%s\" --url \"https://%s%s\" --header \"content-type: application/json\" --header \"X-SIGNATURE: %s, signature=%s\" --data \"%s\"", method, host, uri, message, signature, data_to_show));
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. PHP
<\?php
use \Firebase\JWT\JWT;
use \DateTimeZone;
use \DateTime;
require __DIR__ . '/vendor/autoload.php';
function create_signature($uri, $payload, $method, $client_id, $host, $timestamp, $private_key) {
$json_payload = json_encode($payload, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE|JSON_PRESERVE_ZERO_FRACTION);
$b64_payload = base64_encode($json_payload);
$message = "client_id=$client_id, host=$host, method=$method, payload=$b64_payload, timestamp=$timestamp, uri=$uri";
$private_key = openssl_pkey_get_private($private_key);
openssl_sign($message, $signature, $private_key, OPENSSL_ALGO_SHA256);
return array(base64_encode($signature), $b64_payload);
}
function create_signature_from_message($message, $private_key) {
$private_key = openssl_pkey_get_private($private_key);
openssl_sign($message, $signature, $private_key, OPENSSL_ALGO_SHA256);
return base64_encode($signature);
}
function verify_sign($public_key, $signature, $data) {
$rsakey = openssl_pkey_get_public($public_key);
$result = openssl_verify($data, base64_decode($signature), $rsakey, OPENSSL_ALGO_SHA256);
return $result == 1;
}
$EST = new DateTimeZone('Africa/Casablanca');
$date_time = new DateTime('now', $EST);
$private_key = '-----BEGIN RSA PRIVATE KEY-----
MIIE...
-----END RSA PRIVATE KEY-----';
$uri = '/api/v1/shops/f09fbdb6-3245-4f2b-a928-23669a0b93a3/earn-requests';
$method = 'POST';
$host = 'staging-app.kenzup.com';
$client_id = 'renault-staging-shop';
$timestamp = $date_time->format("Y-m-d\TH:i:sO");
$order_id = uniqid();
$terminal_id = uniqid();
$data = array('agent_id' => null, 'agent_mobilenumber' => null, 'agent_name' => null, 'amount' => 1.0, 'currency' => 'MAD', 'customer' => null, 'force' => false, 'order_id' => $order_id, 'terminal_id' => $terminal_id , 'time' => $timestamp);
$data_to_show = '{"agent_id":null, "agent_mobilenumber":null, "agent_name":null, "amount":1.0, "currency":"MAD", "customer":null, "force":false, "order_id":"'.$order_id.'", "terminal_id":"'.$terminal_id.'", "time":"'.$timestamp.'"}';
list($signature, $payload) = create_signature($uri, $data, $method, $client_id, $host, $timestamp, $private_key);
$message = "client_id=$client_id, host=$host, method=$method, payload=$payload, timestamp=$timestamp, uri=$uri";
echo 'curl --request "'.$method.'" --url "https://'.$host.$uri.'" --header "content-type: application/json" --header "X-SIGNATURE: '.$message.', signature='.$signature.'" --data "'.$data_to_show.'"';
\?>
4. Bash
#!/bin/bash
# Import the private key
privateKeyFile=$(mktemp)
privateKey="..." # See 4.5 for Test Vectors
echo "${privateKey}" > ${privateKeyFile}
# Import the public key (Optional)
# This public key is necessary only if you want to verify the
# signature before making the request
publicKeyFile="${privateKeyFile}.pub"
publicKey="..." # See 4.5 for Test Vectors
echo "${publicKey}" > ${publicKeyFile}
# Request parameters
sandboxShopId="6842310a-8e80-4138-8ec3-f59905019053"
clientId="client-0"
host="staging-app.kenzup.com"
apiVersion="v2"
method="POST"
terminalId=$(uuidgen)
orderId=$(uuidgen)
orderTimestamp="$(date -u '+%F %TZ')"
signatureTimestamp="$(date -u '+%F %TZ')"
uri="/api/${apiVersion}/shops/${sandboxShopId}/payment-requests"
data="{\"amount\": 1, \"currency\": \"MAD\", \"order_id\": \"${orderId}\", \"terminal_id\": \"${terminalId}\", \"time\": \"${orderTimestamp}\"}"
# Hash the payload using base64
payload=`echo -n "${data}" | base64`
# Create canonical message
message="client_id=${clientId}, host=${host}, method=${method}, payload=${payload}, timestamp=${signatureTimestamp}, uri=${uri}"
# Create temporary files to hold the signature
messageFile=$(mktemp)
signatureFile=$(mktemp)
echo -n "${message}" > ${messageFile}
# Generate the signature
openssl dgst -sha256 -out "${signatureFile}" -sign "${privateKeyFile}" "${messageFile}"
openssl dgst -sha256 -verify "${publicKeyFile}" -signature "${signatureFile}" "${messageFile}"
signature=$(cat "${signatureFile}" | base64)
echo "DATA:"
echo "${data}"
echo ""
echo "BASE64 PAYLOAD:"
echo "${payload}"
echo ""
echo "SIGNATURE:"
echo "${signature}"
echo ""
echo "X-SIGNATURE HEADER:"
echo "${message}, signature=${signature}"
echo ""
# Submit the request using cURL
curl --request "${method}" \
--url "https://${host}${uri}" \
--header 'content-type: application/json' \
--header "X-SIGNATURE: ${message}, signature=${signature}" \
--data "${data}"
4.7 Defining a valid certificate
On joining the Kenz'up service, the client will be invited in sharing a list of terminal id's associated with a shop and providing a public key to be used to validate the signature.
Example:
| Terminal ID | Shop Name | Public Key |
|---|---|---|
| Terminal_001 | Shop 1 | MIGfMA0GCSqGSIb3DQEBA... |
| Terminal_002 | Shop 1 | BAQUAA4GNADCBiQKBgQD... |
| Terminal_003 | Shop 2 | DJIVAUvYhfpup5hUZYVv1dE.. |
4.8 Test vectors
You can use these values to test your implementation of the signature algorithm.
These are testing values. Do not use these values in production.
Client ID:
client_id=client-0
Shop ID
shop_id=6842310a-8e80-4138-8ec3-f59905019053
Private Key:
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----
Public Key:
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAqAerlStbJoOFl5LrC4gy
pQA4nAYeAbxfumbo+lJRl+y0O5SgL9QxerazmHIg9xr9F+UZAIlQt2ApNfyshiqM
qyxaEl03wmeIEk9hiTVIqEWz6KbN6LRxRaDSAusBzdDw+rk75eQFuVQT8So/gl58
J81KiSzwKeVCVSnzVf7BCI94qy3IRUub+TfFs5aeI/lkaiaI7wrulOk9cBz4/g21
l8BTLuvUVNkD8s6CFCkRoVPQKo1oXMyZ61Ee9CfPSBFJBQqBGjRsGASlChK0N/ZI
zXAE2V13ERbtvb6UTDC09F2S6d7lvZ1zWGMKuf8S+MxrOoMFawk7i6NGh4vUgmzy
yskwSdYtVAtrUhSoq+ffEzlwD+3/lkD7J7ls02JdS5e/4rBZDaSt3bZVKH6p74PG
FWLOcBtsjdQKvuGLvLnrS8sodNVcT0+dP4N9aGPwj9nxKeppUw2RNNb1wTF4ENit
zk5KDcrJA6aIR70JYus8lgHGvSqRV3EaO6o/7lPUrd7JAgMBAAE=
-----END PUBLIC KEY-----