I am working on a project to write to and read from a TP Link / Kaza power strip or smart plug.
The data that is sent is encrypted json that has been "autokey encrypted".
So far I have been able to convert a typescript encrypt function and it works well. I get the expected result. However, I need to add a "header" to my encrypted data. That data is 3 null bytes followed by a byte that is a measure of the length of the encrypted bytes.
The same typescript has this bit to encrypt with headers, however, I've hit a bit of a wall trying to convert it to something usable. Can someone nudge me along the path ?
First are the two typescript functions: (borrowed from tplink-smarthome-crypto/index.ts at main · plasticrake/tplink-smarthome-crypto · GitHub)
/**
* Encrypts input where each byte is XOR'd with the previous encrypted byte.
*
* @param input - Data to encrypt
* @param firstKey - Value to XOR first byte of input
* @returns encrypted buffer
*/
export function encrypt(input: Buffer | string, firstKey = 0xab): Buffer {
const buf = Buffer.from(input);
let key = firstKey;
for (let i = 0; i < buf.length; i += 1) {
// eslint-disable-next-line no-bitwise
buf[i] ^= key;
key = buf[i];
}
return buf;
}
/**
* Encrypts input that has a 4 byte big-endian length header;
* each byte is XOR'd with the previous encrypted byte.
*
* @param input - Data to encrypt
* @param firstKey - Value to XOR first byte of input
* @returns encrypted buffer with header
*/
export function encryptWithHeader(
input: Buffer | string,
firstKey = 0xab
): Buffer {
const msgBuf = encrypt(input, firstKey);
const outBuf = Buffer.alloc(msgBuf.length + 4);
outBuf.writeUInt32BE(msgBuf.length, 0);
msgBuf.copy(outBuf, 4);
return outBuf;
}
Second is what I have so far. This part works well and produces the expected results
// This part works well and produces the expected results
String encrypt(String input)
{
int16_t firstKey = 0xab;
String buf;
int key;
int i;
buf = input;
key = firstKey;
i = 0;
for (;i < buf.length();(i = i + 1))
{
buf[i] ^= key;
key = buf[i];
}
return buf;
}
// This does not function yet, as I'm pretty lost..
// This was orginally converted from typescript with https://andrei-markeev.github.io/ts2c/
// I started work on converting this, but ran into errors I don't know how to solve.
String encryptWithHeader(String input){
String msgBuf;
String outBuf;
int16_t firstKey = 0xab;
char * null = NULL;
msgBuf = encrypt(input);
outBuf = msgBuf.length() +1;
//this is where I got lost...
assert(null != NULL);
null[0] = '\0';
strncat(null, outBuf, msgBuf.length());
str_int16_t_cat(null, 4);
outBuf = msgBuf + 4
return outBuf;
}
Finally, the data:
//this is the unencrypted json
String offMsg = "{\"system\":{\"set_relay_state\":{\"state\":0}}}";
//current encrypt function produces:
d0f281f88bff9af7d5ef94b6c5a0d48bf99cf091e8b7c4b0d1a5c0e2d8a381f286e793f6d4eedea3dea3
//the working "withheaders" would produce:
00002ad0f281f88bff9af7d5ef94b6c5a0d48bf99cf091e8b7c4b0d1a5c0e2d8a381f286e793f6d4eedea3dea3
Admittedly my C/C++ ability is very limited and I can spell typescript, that's about all. I have a very extensive history with PHP. As useful as that is. So, I understand the basics of data structures and whatnot, but I'm venturing off into areas I've never been in. Any help would be greatly appreciated.