Now use this code everywhere for the rest of the exercises. Here's a simple rule of thumb:
Always operate on raw bytes, never on encoded strings. Only use hex and base64 for pretty-printing.
Write a function that takes two equal-length buffers and produces their XOR sum.
... after hex decoding, when xor'd against:
... should produce:
The hex encoded string:
... has been XOR'd against a single character. Find the key, decrypt the message.
Write code to do this 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.
Tune your algorithm until this works.
One of the 60-character strings at:
has been encrypted by single-character XOR. Find it. (Your code from #3 should help.)
Write the code to encrypt the string:
Burning 'em, if you ain't quick and nimble I go crazy when I hear a cymbal
Under the key "ICE", using repeating-key XOR. It should come out to:
Encrypt a bunch of stuff using your repeating-key XOR function. Get a feel for it.
The buffer at the following location:
is base64-encoded repeating-key XOR. Break it.
a. Let KEYSIZE be the guessed length of the key; try values from 2 to (say) 40.
b. Write a function to compute the edit distance/Hamming distance between two strings. The Hamming distance is just the number of differing bits. The distance between:
this is a test
c. For each KEYSIZE, take the FIRST KEYSIZE worth of bytes, and the SECOND KEYSIZE worth of bytes, and find the edit distance between them. Normalize this result by dividing by KEYSIZE.
d. The KEYSIZE with the smallest normalized edit distance is probably the key. You could proceed perhaps with the smallest 2-3 KEYSIZE values. Or take 4 KEYSIZE blocks instead of 2 and average the distances.
e. Now that you probably know the KEYSIZE: break the ciphertext into blocks of KEYSIZE length.
f. Now transpose the blocks: make a block that is the first byte of every block, and a block that is the second byte of every block, and so on.
g. Solve each block as if it was single-character XOR. You already have code to do this.
e. For each block, the single-byte XOR key that produces the best looking histogram is the repeating-key XOR key byte for that block. Put them together and you have the key.
The Base64-encoded content at the following location:
Has been encrypted via AES-128 in ECB mode under the key
(I like "YELLOW SUBMARINE" because it's exactly 16 bytes long).
Use OpenSSL::Cipher and give it AES-128-ECB as the cipher.
At the following URL are a bunch of hex-encoded ciphertexts:
One of them is ECB encrypted. Detect it.
Remember that the problem with ECB is that it is stateless and deterministic; the same 16 byte plaintext block will always produce the same 16 byte ciphertext.