Decrypting the XECryption Algorithm
by Jamie McDonald
I’ve been going through the Hack This Site challenges and found the sixth realistic mission to be good fun. The challenge was to take an email encrypted using the XECryption and decrypt it. A little background knowledge on the algorithm was required to understand how to decrypt it.
The secret key for XECryption is created by taking each character of the password, converting them to their ASCII code equivalents and summing them together. Each character is encrypted by converting it to it’s ASCII code equivalent and then adding the value of the key to it. It is then divided into three three-digit numbers separated by a full-stop each. So as an example we will use the secret key “hello” and the letter “s” as a message:
hello = 104 + 101 + 108 + 108 + 111 = 532
s + 532 = 115 + 532 = 647
ciphertext = .214.265.263.
XECryption can easily be decrypted with the secret key by taking the sum of the three digits, minus the secret key and convert the value from an ASCII code to the character.
Knowing this information is useful but without the secret key we have to do some analysis on the ciphertext. By grouping the text into the sets of 3 numbers and finding their sums it is possible to do some frequency analysis on the ciphertext. According to studies, the most frequent letter in the alphabet is “e” however given the modern context of the scenario the most common character is likely to be a space. If you take the value of the most common character and subtract 32 (the ASCII code of a space character) you have a possible candidate for a key. The only thing left to do is to subtract the key from each of the three digit groupings and convert them from the ASCII codes to the character equivalents. If the most common character turned out not to be a space then other characters would have to be tried.
Being lazy, I wrote a script in Python to do this. However, I only learnt Python today so it might be inefficient or horribly coded, but it works and got me my solution to the challenge.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #!/usr/bin/env python # Open the encrypted file file = open("cipher.txt", "r") # Read the file and split the numbers into a list ciphertext = file.read().replace("."," ").split() z = 0 L = list() # Group the numbers into blocks of 3 and sum them for i, x in enumerate(ciphertext): if (i != 0) & ((i % 3) == 0): z += 1 try: L[z] += int(x) except IndexError: L.append(int(x)) # Find the most common element and subtract 32 (ascii value of space) to get the key key = max(set(L), key=L.count) - 32 # Subtract key from each value and convert from it's ascii value to its character form for i,x in enumerate(L): # print i, x, x - key L[i] = chr(x - key) # Print the decrypted text print "".join(L) |
After doing this, and when writing up this post, I discovered that there already exist solutions in Python and other languages for this that are probably better, but this was much more fun
Great article Jamie. Helped me a lot.
Thanks for sharing.