hemisemidemipresent / NKsku

A multi-purpose library for decrypting Profile.save and other data, as well as making valid requests to NK's server
https://www.npmjs.com/package/nksku
13 stars 2 forks source link
bloons bloons-td-6 btd6 dgdata javascript ninja-kiwi

NKsku

This repo contains 3 parts

  1. DGDATA
  2. NK's Profile.save
  3. NK's sigs and nonces

Installation

for a npm project simply use

npm i nksku

Documentation - Table of Contents

Credit where credit is due

DGDATA code was from this npm package before it became a rickroll

Profile.save decryption was heavily referenced from averysumener's c++ Profile.save thingy and BowDown097's provided c# code. This would not have been possible without them.

sig and nonce formulas would not be available would not have been possible without Woob and Coral#0762

DGDATA - Data Scheme

How to use

Primitively, you can just fetch the url

const nksku = require('nksku');
const url = "https://";

request(url, { encoding: null }, (err, res, body) => {
    if (err) {
        // handle error code
    }
    let decodedBody = nksku.dgdata.decode(body).toString('utf-8');
    let json = JSON.parse(decodedBody);
}

Ripped off documentation for DGDATA

(Formerly known as NKTools)

arrayToStr

Converts an array of bytes to text

Parameters

Returns string A string

strToArray

Converts a string to a utf-8 array

Parameters

Returns Array Returns an array of numbers

decode

Decodes a string or array of DGData Arrays work best, as strings loose data due to utf-8 / unicode

Parameters

Returns string This is the result of the data

encode

Encodes a string of data

Parameters

Returns array An array of bytes

secondHash

Encodes a number - You really shouldn't have to deal with this

Parameters

Returns number The result

hash

Hashes some data - You really shouldn't have to deal with this unless you want to manually verify the program

Parameters

Returns array An array of bytes

Profile.save

Usage

unpacking

just some standard stuff, did something a bit different using promisify in this example

const { nksave } = require('nksku');
const fs = require('fs');

const { promisify } = require('util');
const readFile = promisify(fs.readFile);

async function main() {
    let bytes = await readFile('./path/to/Profile.save', null);
    let json = nksave.unpack(bytes);
    // log it, write to file, etc
}
main();

packing

similar to above example

const { nksave } = require('nksku');
const fs = require('fs');

const { promisify } = require('util');
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.readFile);

async function main() {
    let bytes = await readFile('./path/to/editedfile.json', null);
    let encoded = nksave.pack(bytes);
    await writeFile('./path/to/Profile.save', encoded);
}
main();

Functions

unpack

Decrypts a given Buffer of an NK save file

Parameters

Returns string string containing the decrypted text in Profile.save

pack

Encrypts a given Buffer the same way as NK encrypts its Profile.save Parameters

Returns Buffer buffer to write data to a .save file

signatures and nonces

For manual generation of sig see https://signonce.netlify.app/

Usage

const { signonce } = require('nksku');

// generate a nonce
let nonce = signonce.generate64BitNonce();

// signature finder

// example 1: let it generate from a string
let obj = '{}';
let sig = signonce.sign(obj, nonce);

// example 1.5: let it generate w/o a nonce, used for validating responses
let obj = '{}';
let sig = signonce.sign(obj);

// example 2: sign from an obj
let obj = {};
let sig = signonce.sign(obj, nonce);

// example 2.5: let it generate w/o a nonce, used for validating responses
let obj = {};
let sig = signonce.sign(obj);

// example 3: sign from a whole request (probably for checking)
let obj = {
    data: '{}',
    auth: {
        session: null,
        appID: 11,
        skuID: 35,
        device: 'vrej'
    },
    sig: 'dc1027f28bc1ba12f6ef770588cdd1f4',
    nonce: '6129188331007147111'
};
let sig = signonce.sign(obj); // undefined nonce = use object's nonce

// example 4: same as example 3 but for some reason u put in a nonce
let obj = {
    data: '{}',
    auth: {
        session: null,
        appID: 11,
        skuID: 35,
        device: 'vrej'
    },
    sig: 'dc1027f28bc1ba12f6ef770588cdd1f4',
    nonce: '6129188331007147111'
};
let nonce = obj.nonce;
let sig = signonce.sign(obj, nonce);

Extras

./nk-server-code contains NK's actual server code (not all of them, and not in correct folder structure)