NOTE: The “secret” provided should never be given out to anyone except the client as well as the process outlined below.
- Ensure to have the API key you will be using to send the install as well as the app secret for your account which is provided by the Kochava account management team.
- Take the entire JSON body of the request you will be sending to Kochava and run it through a SHA1 hash.
- With the payload hash from the previous step, prepend the secret key that Kochava provides to the payload hash. Then perform a SHA-256 hmac hash on that value(secret key+payload hash) with your API key as the secret.
- Add the hash value provided as a token in a ‘Kochava-Auth-Token’ header along with your API key in the ‘Kochava-Api-Key’ header.
- Send the JSON body with the given headers and our system will run the same check when the payload is ingested to confirm the correct secret and process was used.
Post Endpoint:
http://control.kochava.com/track/json
Sample Header Data:
Kochava-Api-Key: {Your API Key}
Kochava-Auth-Token: {Your Auth Token}
Sample Post Data:
{
"action": "install",
"kochava_app_id": "koconversionsdemo174ea19bc63928c",
"app_ver": "3.3.0",
"data": {
"origination_ip": "69.224.141.777",
"device_ver": "iPhone-iOS-9.3.4",
"device_ids": {
"idfa": "kochava-test-idfa-2015-12-09-12",
"idfv": "333BA75-FE08-AAA4-9EF0-98A6AD293FEC",
"adid": "",
"android_id": ""
}
}
}
It is critical that the shared secret related to the API key is not shared outside of the application used to send S2S payloads to Kochava. If the secret is known along with the process of generating the Authorization Token fraudulent payloads can be sent with valid hashes and Kochava servers will not be able to detect any breach in authorization.
If you believe that the secret key is ever compromised it is highly recommended that you reach out to your Kochava account management team to generate a new API-Secret key pair for your application to use.
NodeJS Example:
// NodeJS
var crypto = require('crypto');
var https = require('https');
function getPayloadHash(payload) {
return crypto.createHash('sha1').update(payload).digest('hex');
}
function getPayloadChecksum(api_key, secret, payload) {
return crypto.createHmac('sha256', api_key).update(secret + getPayloadHash(payload)).digest('hex');
}
function makeRequest(api_key, secret, payload, callback) {
if (arguments.length !== 4) {
throw new Error("missing argument");
}
if (typeof (payload) === "object") {
payload = JSON.stringify(payload);
} else if (typeof (payload) !== "string") {
throw new Error("payload must a string");
}
payload = payload.replace(/\//g, '\\/');
var options = {
hostname: 'control.kochava.com/track/json',
port: 8081,
path: '/track/json',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload),
'Kochava-Auth-Token': getPayloadChecksum(api_key, secret, payload),
'Kochava-Api-Key': api_key
}
};
var req = https.request(options, callback);
req.on('error', function (e) {
throw new Error("Error encountered: " + e.toString());
});
req.write(payload);
req.end();
}
var payload = {
"action": "session",
"data": {
"event_name": "Doodad",
"language": "en-US",
"identifiers": {
"idfa": "64a57f21-6f56-48a5-972b-57375c34c10a"
}
},
"kochava_app_id": "kos2s-checksum-verification-rk7d1nv"
};
var api_key = 'F5BF7338-04CA-4E07-97C8-49E20C409E91';
var secret = '9x6C9uN3c1';
function callback(res) {
console.log("statuscode: " + res.statusCode);
res.on('data', function (d) {
console.log(d.toString());
});
}
makeRequest(api_key, secret, payload, callback);
# Python
import hashlib
import hmac
import requests
import json
class KochavaS2SChecksum(object):
def __init__(self, api_key, secret):
self.api_key = api_key
self.secret = secret
def get_payload_hash(self, payload):
return hashlib.sha1(payload.encode('utf-8')).hexdigest()
def get_checksum(self, payload):
return hmac.new(key=self.api_key.encode('utf-8'), msg=(self.secret + self.get_payload_hash(payload)).encode('utf-8'), digestmod=hashlib.sha256).hexdigest()
class KochavaS2SRequest(object):
KOCHAVA_ENDPOINT = 'https://control.kochava.com/track/json.php'
def __init__(self, checksum):
self.checksum = checksum
def make_request(self, payload):
return requests.post(self.KOCHAVA_ENDPOINT, data=json.loads(payload), headers={'Kochava-Auth-Token': self.checksum.get_checksum(payload), 'Kochava-Api-Key': self.checksum.api_key})
def main():
my_s2s_payload = """{"action":"initial","data":{"language":"en-US","identifiers":{"idfa":"64a57f21-6f56-48a5-972b-57375c34c10a"}},"kochava_app_id":"kos2s-checksum-verification-rk7d1nv"}"""
api_key = 'F5BF7338-04CA-4E07-97C8-49E20C409E91'
secret = '9x6C9uN3c1'
s2s_checksum = KochavaS2SChecksum(api_key, secret)
kochava_request = KochavaS2SRequest(s2s_checksum)
r = kochava_request.make_request(my_s2s_payload)
print(r.json())
if __name__ == "__main__":
main()