This is my write up of the fifth Cryptopals challenge, using Python3 as my language of choice. The challenge:
Implement repeating-key XOR
Here is the opening stanza of an important work of the English language:
Burning ’em, if you ain’t quick and nimble
I go crazy when I hear a cymbal
Encrypt it, under the key “ICE”, using repeating-key XOR.
In repeating-key XOR, you’ll sequentially apply each byte of the key; the first byte of plaintext will be XOR’d against I, the next C, the next E, then I again for the 4th byte, and so on.
It should come out to:
Encrypt a bunch of stuff using your repeating-key XOR function. Encrypt your mail. Encrypt your password file. Your .sig file. Get a feel for it. I promise, we aren’t wasting your time with this.
This challenge wasn’t too much different from the challenges involving single-key XOR. We take a message and iterate through each byte, XOR’ing the byte with a single character of the key, which moves to the next key-byte with each iteration. I controlled the key-byte movement using an index, which I initially set to 0 (zero). After XOR’ing the message byte, I check the value of the index to make sure it isn’t the length of the key, and increment the index, so it will point to the next key-byte on the next iteration. Once the length of the index becomes the same size as the key, I reset the index back to 0, thereby moving the key-byte back to the first character.
The challenge also says to “encrypt a bunch of stuff” with repeating-key XOR, so I created a tool to do this. The tool, repeating_key_xor_encrypt_decrypt.py, is available on my GitHub and here is the basic usage:
usage: repeating_key_xor_encrypt_decrypt.py [-h] [-k KEY] [-d DATA] [-f FILE] [-ue] [-be] [-xe] [-ud] [-bd] [-xd] [-o OUTFILE] optional arguments: -h, --help show this help message and exit -k KEY, --key KEY Specify the key to encrypt/decrypt with -d DATA, --data DATA Specify the data as a string -f FILE, --file FILE Specify a file containing the data -ue, --url_encode Encode the output with URL encoding -be, --base64_encode Encode the output using Base64 -xe, --hex_encode Encode the output as hex. -ud, --url_decode Decode the input with URL encoding -bd, --base64_decode Decode the input using Base64 -xd, --hex_decode Decode the input as hex. -o OUTFILE, --outfile OUTFILE Specify the name of the output file
Encrypt a message passed as a string with the key ‘MySecretPassword’, output as hex:
python3 repeating_key_xor_encrypt_decrypt.py -d "This is a secret message" -k MySecretPassword -xe b'19113a16431b165431410016141d17106d14361610130211'
To decrypt that same message:
python3 repeating_key_xor_encrypt_decrypt.py -d 19113a16431b165431410016141d17106d14361610130211 -k MySecretPassword -xd b'This is a secret message'
To encrypt a message, encode with Base64, and output to a file:
python3 repeating_key_xor_encrypt_decrypt.py -d "This is another secret message. I'll put it in a file" -k MySecretPassword -be -o mysecret.txt b'GRE6FkMbFlQxDxwHHwoARD4cMBcGBkUZNRIAEhAKXEQEXj8JQwIQAHAIB1MeAVIFbR86CQY='
To decrypt that message from the file:
python3 repeating_key_xor_encrypt_decrypt.py -f mysecret.txt -k MySecretPassword -bd b"This is another secret message. I'll put it in a file"
The tool is only lightly tested so bugs are a possibility.