XOR Cipher: Implementation, Analysis Of The Encryption Algorithm In Python
While working on one of the NATAS challenges from overthewire.com, I encountered the XOR encryption algorithm. It is a symmetric-key algorithm, meaning the same key is used for both encryption and decryption
Implementation of XOR encryption algorithm in Python
XOR encryption can be implemented as code below
def xor_encryption(text, key):
encrypted = ""
for i in range(len(text)):
encrypted += chr(ord(text[i]) ^ ord(key[i % len(key)]))
return encrypted
To check how it works lets define text which will be encrypted and key. Additionally to check tex and encrypted text length lets add print function with length of strings.
text = "Text which will be encrypted"
key = "SECRET_KEY"
encrypted = xor_encryption(text, key)
print(f'Encrypted Text: {encrypted}')
print(f'Encrypted Text length: {len(encrypted)}')
print(f'Plain Text length: {len(text)}')
It will return:
Encrypted Text: ;&e#7"&1s2*>)t=.e<=&1+5 :/
Encrypted Text length: 28
Plain Text length: 28
Now we are sure that encrypted and plain text’s are same length.
Prove that XOR encryption is Symmetric-key algorithm
To check that this code is Symmetric-key algorithm lets decode encrypted text with the same function
decrypted = xor_encryption(encrypted, key)
print(f'Decrypted Text: {decrypted}')
It will return:
Encrypted Text: Text which will be encrypted
So we are sure that XOR algorithm is Symmetric-key algorithm.
Finding the key of XOR algorithm
Lets imagine the case that we have encoded and decoded texts but we haven’t got a key. How to find it? Lets use this part of code:
found_key = xor_encryption(encrypted, decrypted)
print(f'Key: {found_key}')
As we can see we are passing to our xor_encryption function two arguments: encrypted and decrypted strings. As a return we will get:
Key: SECRET_KEYSECRET_KEYSECRET_K
As we can see there is a long string but with repetitive part: SECRET_KEY which is a key.
We can additionally define function which will get this key for us from this long string:
def find_repetitive_part(test_str):
n = len(test_str)
for i in range(1, n // 2 + 1):
part = test_str[:i]
repetitions = n // i
if part * repetitions == test_str[:i * repetitions]:
return part
return "No repetitive part found"
print(f'Key: {find_repetitive_part(found_key)}')
And it will return:
Key: SECRET_KEY
Voila!
Now you know how to:
- Define XOR Encryption function in Python
- Encrypt and decrypt
- Find a missing key