Level 3: Single-byte XOR cipher
Task
The hex encoded string:
1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736
.. has been XOR'd against a single character. Find the key, decrypt the message.
You can do this by hand. But don't: write code to do it for you.
How? Devise some method for "scoring" a piece of English plaintext. Character frequency is a good metric. Evaluate each output and choose the one with the best score.
Achievement Unlocked
You now have our permission to make "ETAOIN SHRDLU" jokes on Twitter.
Explanation
What is a Single-Byte XOR cipher?
A single-byte XOR cipher is a method where each byte of the plaintext is XORed with the same single-byte key.
To decrypt the message, we need to try all 256 possible single-byte values (from 0 to 255) and XOR them against the ciphertext. The correct key will produce a readable English message.
We use a Character Frequency Analysis because English text has predictable letter frequency distributions. By scoring the output based on how closely it resembles typical English text, we can determine which key likely reveals the original message.
Resolution
First, we are going to create a file named task3.py
Understanding the code
The binascii library is imported to manipulate hexadecimal data.
ENGLISH_FREQUENCY
is initialized with the most common English letters.score_text(text)
is a function that takestext
as parameterIt first converts the characters to uppercase with
text.upper()
.Then, it returns the sum of how many characters appear in
ENGLISH_FREQUENCY
.The more common characters the text contains, the higher the score will be.
single_byte_xor_cipher(hex_string)
is a function that decrypts the ciphertext. It takeshex_string
as a parameter.ciphertext
is a variable that stores the byte representation of hex_string.Three variables are created
best_score
, which stores the highest score found.best_key
, which stores the best key found.best_plaintext
, which stores the best plaintext decoded.
Next, a loop is created to try all possible key values (from 0 to 255) because the XOR cipher is applied with a single byte key, which has 256 possible values.
plaintext
stores the result of XORing each byte in ciphertext with the keybytes([byte ^ key for byte in ciphertext])
byte ^ key
XORs every byte in the ciphertext with the current key.the result is converted into bytes
decoded_text
is initialized by decodingplaintext
, ignoring errors.score
stores the result ofscore_text(decoded_text)
.The function then checks if
score > best_score
. If true, the variables are updatedbest_score = score
best_key = key
best_plaintext = decoded_text
Finally, the function returns
best_key
andbest_plaintext
hex_strings
receives the hexadecimal string provided by Cryptopals.key
andplaintext
receive the result ofsingle_byte_xor_cipher(hex_string)
, assigningbest_key
tokey
andbest_plaintext
toplaintext
.Finally, the key character and plaintext are printed.
Result
Last updated