Other pages

Signing a cloud API request

This is a step by step guide to generate a signed URL to access endpoints via the cloud api. There are two types of signing:

Contents

JSON Web Tokens

JSON web tokens are a standard way to sign arbitrary data using a secret that only the server knows. Since the data you are signing is flexible and included in the token itself, it provides more flexibility than traditional signing.

Understanding JSON Web Tokens

There are plenty of libraries available for generating and validating JWT, but at a high level it is pretty simple. A sample token looks like this

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJiaXRibGFzdDpHQnBpenYzeHQyIiwiaWF0IjoxNDM1NTA2MDcxLCJleHAiOjE0MzU1MDk2NzEsInBhdGgiOiIvaW5mbyoifQ.pzAWJLoPvkjh4lwk1ui2dyGBUcYHv2HlWjKeRn0xOnM

It is made up of three parts: a header, claims, and a signature. They are all base64 encoded and separated by a period.

<base64-urlencoded header>.<base64-urlencoded claims>.<base64-urlencoded signature>

When you decode it and break it down it looks like this

Signing JSON Web Tokens

The signature is calculated by taking the base64 encoded values of the headers and claims, concatenating them with a period and using your secret that corresponds to the key you used in the iss claim.

It is recommended to use a library to do this.

Available JWT Libraries

For more libraries check out the JSON Web Token page page.

Here is an example in python

import time
import jwt

headers = {
    'typ': 'JWT',
    'alg': 'HS256'
}

claims = {
    'iss': 'bitblast:' + YOUR_KEY,
    'iat': int(time.time()),
    'exp': int(time.time()) + 3600,  # Expires in one hour
    'path': '/info*'
}

assertion = jwt.encode(claims, YOUR_SECRET_KEY, headers=headers)

print(assertion.decode('utf-8'))

Using the final token

After you have generated the token you should include it as a query string parameter named token. So your final URL might look something like this

/info?src=magnet%3A%3Fxt%3Durn%3Abtih%3ACNKKYRN7WPTEJICNNHGFDHUDFA55HLDK&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJiaXRibGFzdDpHQnBpenYzeHQyIiwiaWF0IjoxNDM1NTA2MDcxLCJleHAiOjE0MzU1MDk2NzEsInBhdGgiOiIvaW5mbyoifQ.pzAWJLoPvkjh4lwk1ui2dyGBUcYHv2HlWjKeRn0xOnM

Traditional Signing

Constructing a URL

First pick the endpoint that you want from the list of endpoints. For this example we will be using the info endpoint.

The base url is

https://cloud.bitblast.io/info

We only care about the ending though /info. The magnet URL for the torrent we want to get info about is

magnet:?xt=urn:btih:CNKKYRN7WPTEJICNNHGFDHUDFA55HLDK

This means the uri we want to request is

var magnetUrl = 'magnet:?xt=urn:btih:CNKKYRN7WPTEJICNNHGFDHUDFA55HLDK';
var baseUri = '/info';
var fullUri = baseUri + '?src=' + encodeURIComponent(magnetUrl);

Which turns out to be

/info?src=magnet%3A%3Fxt%3Durn%3Abtih%3ACNKKYRN7WPTEJICNNHGFDHUDFA55HLDK

Computing the signature

The signing mechanism is similar to Amazon S3 so if you are familiar with that then great. First you are going to need to copy your secret key out of your settings.

You need to first generate a UNIX timestamp for when you want your signature to expire.

var expires = Math.round(new Date().getTime() / 1000) + 3600;

Now create an hmac_sha1 hash using your secret key from your settings and add the fullUri and expires to the hash. The signature is the resulting digest base64 encoded.

var hmac = crypto.createHmac('sha1', YOUR_SECRET_KEY);
var digest = hmac.update(fullUri + expires).digest();
var signature = new Buffer(digest).toString('base64');

Putting it all together

After you have the uri and the signature you just need to add a few extra parameters to the end of the url.

&key={YOUR_API_KEY}&exp={EXPIRES_TIMESTAMP}&sig={SIGNATURE}

So now the final URL will look a little something like this

/info?src=magnet%3A%3Fxt%3Durn%3Abtih%3ACNKKYRN7WPTEJICNNHGFDHUDFA55HLDK&key=GBpizv3xt2&exp=1435442273&sig=DqAAHWl4W9hXG5GkeK2/00d2QSw=

It doesn't matter which order you append these parameters, but they have to be the last 3 query parameters included with the URL.