How to crack a weakened TEA block cipher?

2019-05-23 11:30发布

问题:

At the moment I am trying to crack the TEA block cipher in C. It is an assignment and the tea cipher has been weakend so that the key is 2 16-bit numbers.

We have been given the code to encode plaintext using the key and to decode the cipher text with the key also.

I have the some plaintext examples:

  1. plaintext(1234,5678) encoded (3e08,fbab)
  2. plaintext(6789,dabc) encoded (6617,72b5)

Update

The encode method takes in plaintext and a key, encode(plaintext,key1). This occurs again with another key to create the encoded message, encode(ciphertext1,key), which then creates the encoded (3e08,fbab) or encoded (6617,72b5).

How would I go about cracking this cipher?

At the moment, I encode the known plaintext with every possible key; the key size being hex value ffffffff. I write this to file.

But now I am stuck and in need of direction.


How could I use the TEA's weakness of equivalent keys to lower the amount of time it would take to crack the cipher? Also, I am going to use a man in the middle attack.

As when I encode with known plaintext and all key 1s it will create all the encrypted text with associated key and store it in a table.

Then I will decrypt with the known ciphertext that is in my assignment with all the possible values of key2. This will leave me with a table of decrypts that has only been decrypted once.

I can then compare the 2 tables together to see if any of encrpts with key1 match the decrypts with key2.

I would like to use the equilenvent weakness as well, if someone could help me with implmenting this in code that would be great. Any ideas?

回答1:

This is eerily similar to the Double Crypt problem from the IOI '2001 programming contest. The general solution is shown here, it won't give you the code but might point you in the right direction.



回答2:

Don't write your results to a file -- just compare each ciphertext you produce to the known ciphertext, encoding the known plain text with every possible key until one of them produces the right ciphertext. At that point, you've used the correct key. Verify that by encrypting the second known plaintext with the same key to check that it produces the correct output as well.

Edit: the encoding occurring twice is of little consequence. You still get something like this:

for (test_key=0; test_key<max; test_key++)
    if (encrypt(plaintext, test_key) == ciphertext)
        std::cout << "Key = " << test_key << "\n";

The encryption occurring twice means your encrypt would look something like:

return TEA_encrypt(TEA_encrypt(plaintext, key), key);

Edit2: okay, based on the edited question, you apparently have to do the weakened TEA twice, each with its own 16-bit key. You could do that with a single loop like above, and split up the test_key into two independent 16-bit keys, or you could do a nested loop, something like:

for (test_key1=0; test_key1<0xffff; test_key1++)
    for (test_key2=0; test_key2<0xffff; test_key2++)
        if (encrypt(encrypt(plaintext, test_key1), test_key2) == ciphertext)
            // we found the keys.


回答3:

I am not sure if this property holds for 16-bit keys, but 128-bit keys have the property that four keys are equivalent, reducing your search space by four-fold. I do not off the top of my head remember how to find equivalent keys, only that the key space is not as large as it appears. This means that it's susceptible to a related-key attack.

You tagged this as homework, so I am not sure if there are other requirements here, like not using brute force, which it appears that you are attempting to do. If you were to go for a brute force attack, you would probably need to know what the plaintext should look like (like knowing it English, for example).



回答4:

The equivalent keys are easy enough to understand and cut key space by a factor of four. The key is split into four parts. Each cycle of TEA has two rounds. The first uses the first two parts of the key while the second uses the 3rd and 4th parts. Here is a diagram of a single cycle (two rounds) of TEA: (unregistered users are not allowed to include images so here's a link) https://en.wikipedia.org/wiki/File:TEA_InfoBox_Diagram.png

Note: green boxes are addition red circles are XOR

TEA operates on blocks which it splits into two halves. During each round, one half of the block is shifted by 4,0 or -5 bits to the left, has a part of the key or the round constant added to it and then the XOR of the resulting values is added to the other half of the block. Flipping the most significant bit of either key segment flips the same bit in the sums it is used for and by extension the XOR result but has no other effect. Flipping the most significant bit of both key segments used in a round flips the same bit in the XOR product twice leaving it unchanged. Flipping those two bits together doesn't change the block cipher result making the flipped key equivalent to the original. This can be done for both the (first/second) and (third/fourth) key segments reducing the effective number of keys by a factor of four.



回答5:

Given the (modest) size of your encryption key, you can afford to create a pre-calculated table (use the same code given above, and store data in large chuncks of memory - if you don have enough RAM, dump the chuncks to disk and keep an addressing scheme so you can lookup them in a proper order).

Doing this will let you cover the whole domain and finding a solution will then be done in real-time (one single table lookup).

The same trick (key truncation) was used (not a long time ago) in leading Office software. They now use non-random data to generate the encryption keys -which (at best) leads to the same result. In practice, the ability to know encryption keys before they are generated (because the so-called random generator is predictable) is even more desirable than key-truncation (it leads to the same result -but without the hurdle of having to build and store rainbow tables).

This is called the march of progress...