Friday, June 30, 2017

Encrypting messages with an XOR cipher

In this post, I will go through the logical XOR operation, show how it can be used to encrypt/decrypt strings and then introduce a python script that automates this process.

 

XOR


XOR (Exclusive or) is a logical operation. It outputs 'true' when exactly one of the inputs is 'true'. Here's a truth table of XOR where 0's are 'false' and 1's are 'true'.


Using XOR to Encrypt/Decrypt Strings

 

Encryption

I have a string "hello", this will be the plaintext message which I want to encrypt, which is represented as follows in binary:

"01101000 01100101 01101100 01101100 01101111"

 Each 0 or 1 is a bit and 8 bits create a byte. Each byte represents one letter in "hello".

I have a second string "world", this will be the key to encrypt/decrypt my plaintext message, which is represented as follows in binary:

"01110111 01101111 01110010 01101100 01100100"

Again, each letter in "world" is represented by a byte or 8 bits.

Referring to the above image, "hello" will be InputA and "world" will be InputB. We will now compute the output using XOR.
  
01101000 01100101 01101100 01101100 01101111 (hello) (our plaintext)
01110111 01101111 01110010 01101100 01100100 (world) (our key)

Here's the first byte encrypted in detail, you can do the rest on your own.

01101000 (first byte of our plaintext)
01110111 (first byte of our key)

0 XOR 0 = 0
1 XOR 1 = 0
1 XOR 1 = 0
0 XOR 1 = 1
1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 1 = 1
0 XOR 1 = 1

The first byte of our encrypted message is 00011111 as shown below. Repeat this for the rest of the bytes to obtain the output shown below.

00011111 00001010 00011110 00000000 00001011 (non-readable ASCII characters)

The output in binary is composed of characters that cannot be represented as normal letters or numbers. They are control characters that the computer understands to perform various operations.

So what have we done here? We've taken a plaintext string, "hello", XORed it with a key string "world" and obtained a non-readable output. This is not always the case, there are times where the output will have characters from the alphabet and numbers. The output of this XOR operation is called our ciphertext. In cryptography, ciphertext is a fancy way of saying encrypted plaintext message.

Great! Now we can send this binary message to someone, but how will they extract our plaintext from it?

Decryption

 

00011111 00001010 00011110 00000000 00001011 (non-readable ASCII characters)
01110111 01101111 01110010 01101100 01100100 (world) (shared key)

If someone received this message in binary and knew the key, they could XOR the cipher text with the key and obtain the original message. Let's go through it.

Here's the first byte decrypted in detail, you can do the rest on your own.

00011111 (First byte of our cipher text)
01110111 (First byte of our key)

0 XOR 0 = 0
0 XOR 1 = 1
0 XOR 1 = 1
1 XOR 1 = 0
1 XOR 0 = 1
1 XOR 1 = 0
1 XOR 1 = 0
1 XOR 1 = 0

The first byte is 01101000 which matches our original message and is of course, the character 'h'.

Repeat this for the rest of the bytes and you will obtain the original message 'hello'.

01101000 01100101 01101100 01101100 01101111 (hello) (our plaintext)

We can now send encrypted messages and the recipient can decrypt them. Secure communication! Not really, for your message to be secure from any snoopers, your key must be completely random and unpredictable.


Securing Messages with XOR alone

- Your key must be longer than your plain text message
- Your key must be TRULY random (no bashing on your keyboard doesn't count)
- The random key you use is a One-Time pad, it must be discarded and never used again so that people cannot use the key to decrypt future messages
- The key must be communicated to the recipient over a secure line (or in person)

As you can see, XOR alone is not a good method for truly secure communication because it is a linear operation (a given input always has the same output). However, it is still useful in cryptography because the XOR operation can be performed quickly to encrypt messages in a stream (as the data is created it cant be encrypted and sent off).

Automating the Process

xor_encrypt_master.py

The script will prompt you whether you want to encrypt or decrypt.

If you select encrypt, it will ask you for a plain text message and a key. Once you enter these, it will ask you the name of the *.pickle file you want to save your message in.

If you select decrypt, it will ask for the name of the *.pickle file you want to encrypt and then the key. It will then output the plain text message using the key. Note, if the key you used is incorrect it will still attempt to output the plain text message (but it will obviously be wrong).


encrypt
 

decrypt
 


The latest copy of my code will be kept here: https://github.com/justinbui/XORcipher


Concluding Remarks


I wrote this for educational purposes to get a better idea of how the XOR cipher works and practice Python. I hope you learned something from reading! I'm not liable for anything you do with the information presented.