Friday, August 1, 2014

XOR a string or file with a key in Python

Here is an elegant example about how to XOR a string using a key with Python's itertools cycle:

>>> from itertools import cycle
>>> 
>>> def do_xor(key, str):
...     str = str.replace(' ', '').decode('hex')
...     key = ''.join(key.split()[::-1]).decode('hex')
...     
...     return ''.join([chr(ord(a) ^ ord(b)) for a,b in zip(str, cycle(key))])
... 
>>> message = "8E D8 51 66 8B D9 03 67 8D FE 0A 3E E1 97 15 13"
>>> key = "13 37 ba be"
>>> 
>>> print do_xor(key, message)
0bfu5c4t3D=-_-"
>>>

If your string isn't in a hexadecimal representation, just remove the "decode('hex')" bits.

Following up on the example above, here is a script that allows quick and easy file encryption. Just chose a key that you will remember and this script will help easily protecting sensitive information on disk:

import os, sys
from itertools import cycle

if len(sys.argv) != 3:
 print "usage: %s <filename> <key>" % sys.argv[0]
 sys.exit()

if os.path.exists(sys.argv[1]):
 data = open(sys.argv[1]).read()
 xored = [chr(ord(a) ^ ord(b)) for a,b in zip(data, cycle(sys.argv[2]))]
 
 open(sys.argv[1], 'w').write(''.join(xored))

 print "file xored"
 
else:
 print "%s: file not found" % sys.argv[1]

Example usage:

user@host:~$ cat /tmp/a
this is a simple text file.
user@host:~$ python xorfile.py /tmp/a Sup3rS3cr3t
file xored
user@host:~$ cat /tmp/a
<... some unprintable characters ...>
user@host:~$ python xorfile.py /tmp/a Sup3rS3cr3t
file xored
user@host:~$ cat /tmp/a
this is a simple text file.
user@host:~$