Search code examples
javascriptnode.jsxor

Decipher XOR in node js


I am making a websocket server and I am stuck on one part. Deciphering the XOR. I have the key and the data. I made sure the data was the same length as the key but I still have this problem.

The problem
When I decipher data, I sometimes get a part of the data. Example:
datasend turns into:
sep
The key is ec1ee034ec1ee034 and the data is 887f94559f7b8e50. I know its not a problem with the data because I used this website that deciphers data. When I put in the key and data I get datasend.
(I got the hex data 73657000 when un-xoring it)
It should be 6461746173656E64 according to the above mentioned website.

Here is my code:

const hextext = (parseInt(newkey, 16)^parseInt(rawdata, 16)).toString(16);   
// I had to convert this to a number for the xor to work
const realtext = Buffer.from(hextext, "hex").toString("utf-8")
// The above converts the hex into utf8 text

I tried hard coding it and it still does not work. My theory is that the number made from the hex data is so big that it becomes a floating point number (it does) but I have no idea how to solve this.

Any ideas?


Solution

  • The problem is that your encoded values are much larger than 2^32, therefore you loose information when you convert them to numbers and xor.

    You can process both strings on a byte-by-byte basis:

    key = 'ec1ee034ec1ee034'
    str = '887f94559f7b8e50'
    
    
    let keyBuf = Buffer.from(key, 'hex')
    let strBuf = Buffer.from(str, 'hex')
    let outBuf = Buffer.alloc(strBuf.length)
    
    for (let n = 0; n < strBuf.length; n++)
        outBuf[n] = strBuf[n] ^ keyBuf[n % keyBuf.length]
    
    console.log(outBuf.toString())
    

    or use BigInts to xor them in one go:

    keyNum = BigInt('0x' + key)
    strNum = BigInt('0x' + str)
    
    decoded = keyNum ^ strNum
    
    outBuf = Buffer.from(decoded.toString(16), 'hex')
    
    console.log(outBuf.toString())
    

    The first method has an advantage that the key can be shorter than the text, thus allowing for "cycled" xor encoding.