Cryptopals challenge 5: Repeating-key XOR encryption

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:

0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272

a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f

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.

In previous posts I’ve given a background on XOR, and then implemented a single key XOR brute force. In this challenge the goal is to encrypt a message using repeating key XOR. Here is my solution:

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.

Leave a Reply

Your email address will not be published. Required fields are marked *