XOR Encryption on Unicode Strings

时间:2019-04-08 13:51:46

标签: python python-3.x encryption xor

I'm currently attempting to do some basic XOR encryption on some plain text, but can't seem to get it working. I've found the typical solutions online, but all of them tend to throw errors, and I'm unfortunately not quite familiar with all the byte/encoding stuff yet.

Here is the most common solution I found online:

def xor_crypt_string(data, key, encode = False, decode = False):
    if decode:
        data = base64.decodestring(data)
    xored = ''.join(chr(ord(x) ^ ord(y)) for (x,y) in zip(data, cycle(key)))
    if encode:
        return base64.encodestring(xored).strip()
    return xored

However, when I run it, I get

TypeError: expected bytes-like object, not str

I've also tried:

key = "mykey"
msg = "this is an example msg"
encrypted = [ chr(ord(a) ^ ord(b)) for (a, b) in zip(msg, cycle(key)) ]
decrypted = [ a ^ b for (a,b) in zip(bytes(encrypted)) ]

The encryption stage seems to work great, but when decrypting I get hit with a

TypeError: 'str' object cannot be interpreted as an integer

I just can't seem to get these solutions to work for me, and am wondering what the case is. For further information, my data and key are simply plain text.

This is a complete guess, but what might be throwing it off is that my data might be formatted or encoded weirdly? My data sometimes will be blank, and sometimes will include emojis (so Unicode I think?) if that matters at all. My encryption input is essentially any character / format you can think of.

To clarify, I'm using Python 3.

Update:

Other attempts:

When encoding the string prior to encrypting, such as

xor_crypt_string(data.encode('utf-8'), key, encode=True)

It then complains about the ord casting. I then tried removing the casting, but realized the key is still a string, and wasn't able to resolve how to deal with this discrepency. I.e. when,

''.join(chr(x ^ ord(y)) for (x,y) in zip(data, cycle(key)))

Error:
unsupported operand type(s) for ^: 'int' and 'str'
''.join(chr(x ^ y) for (x,y) in zip(data, cycle(key)))

Error:
expected bytes-like object, not str

Second Update:

I got it kinda working with this version of the function:

def xor_crypt_string(data, key, encode = False, decode = False):
    if decode:
        data = base64.decodestring(data)
    xored = ''.join(chr(x ^ y) for (x,y) in zip(data, cycle(key)))
    if encode:
        # return base64.encodestring(xored).strip()
        return base64.encodestring(xored.encode('utf-8')).decode('utf-8').replace('\n', '').strip()
    return xored

However, it does not work consistently. Take for example,

// Works great!
before: sounds like ur suppressing ur own creativity
encrypted: EhwRCAASUwgPChZEExNTFxMUEQEBFRIaCgFBBhZGCxYdRAUTFgUSCAUNEh0=
after: sounds like ur suppressing ur own creativity

// Breaks...
before: disliked “wasn’t trolling!!! just agreeing that kaf’s buns can’t compare!!!”
encrypted: BRoXCg0KFgBGwoPDs8O4EQAACsKEw6TDuAdEEhMcCAoIHQNHRUBTDhMSB0QHBgEBAw0PFEQSCRIQRgoSAsKEw6TDuABEBBQdF0YCEgrChMOkw7gHRAUOHhQHExZFR0XCg8Ozw7k=
after: disliked £ð§Õ¢Ëufdk±à¥Å°Üa%awzlk{ye&6$5o`va fuegb~kr%amtt'yvd£÷§Â¢Ëd"`uns can¤å°À¥Üf7ahgcuw6##¦â°×¥Ø

before: lol i didn’t post it, waiting for the right context
encrypted: DRwIRg1BFw0CD8KRw6TDvxVTFAkXFVMNEk1TEwcIBw0IA0EVCxRBBwwDQQENAQwVUwcJDwcBHhU=
after: lol i didn±õ¥Å°Ûs7uzss2~v+2`cncl{g'txp'fg'elrhs2tmifrzs

I'm guessing that certain characters are breaking it - it looks like the non-standard quotations are messing things up.

0 个答案:

没有答案