0

I'm having hard time reversing this algorithm:

decrypt_algorithm = function (text) {
  var parser = new TextParser(text);
  var decrypt_key = [16, 19, 17, 7, 20, 23, 13, 1, 24, 15, 6, 12, 0, 18, 21, 2, 9, 14, 3, 10, 5, 25, 8, 4, 22, 11];
  var text_size = parser.getSize();
  var text_size_without_last_part = text_size - 26;
  var output = [];
  if (text_size_without_last_part > 0) {
      for (var m = 0; m < text_size_without_last_part; m += 26) {
          var word_to_decrypt = [];
          for (var k = 0; k < 26; k++) {
              word_to_decrypt[k] = parser.readNextChar()
          }
          for (var k = 0; k < 26; k++) {
              output[m + k] = word_to_decrypt[decrypt_key[k]]
          }
      }
      var parser_position = parser.getPosition();
      var last_part_size = text_size - text_size_without_last_part - 1;
      if (last_part_text > 0) {
          for (var k = 0; k < last_part_size; k++) {
              output[text_size_without_last_part + k] = parser.readNextChar()
          }
      }
  }
  return output;
};

I don't have any reverse-engineering knowledge, so if you can point me to some resources which explains how to "reverse" a function, it will be really helpful.

I don't need the exact code as an answer, but some guides on how to reverse engineer it by my own is really appreciated.

Edit 1:

After taking a pause and thinking about the algorithm a bit, I understood the problem and it was easier than I thought:

output[decrypt_key[k]] = word_to_decrypt[m + k]

Changing this will revert the algorithm, solving the problem.

3
  • What do you mean by reverse engineering? Do you just want to reverse the algorithm -- and write an encryption function? Because I would not apply the term "reverse engineering" to reading and understanding a block of code. Commented Nov 14, 2012 at 1:37
  • I want to reverse the algorithm, I thought it was called reverse engineering this too, I'll change the tag so! Commented Nov 14, 2012 at 1:38
  • @JimLewis: Sorry I thought it was reverse engineering this type of work too, I've changed it. Commented Nov 14, 2012 at 1:41

2 Answers 2

4

It is a simple permutation cipher. Essentially the decrypt_key is used to rearrange the output

output[m + k] = word_to_decrypt[decrypt_key[k]]


decrypt_key = [16, 19, 17, 7, 20, 23, 13, 1, 24, 15, 6, 12, 0, 18, 21, 2, 9, 14, 3, 10, 5, 25, 8, 4, 22, 11];

or, rearranged:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 16 17 18 19 20 21 22 23 24 25

The code

word_to_decrypt[decrypt_key[k]]

essentially takes the index into the code being "encrypted" and permutes it's words in 26 piece chunks.

You can think of it as just scrambling the words based on the "key", which tells you how it is being scrambled.

e.g,

decrypt_key[0] -> 16
decrypt_key[16] -> 9

which means that the first word(location 0) gets put at location 16 and the word at location 16 gets put at location 9.

Another term would be to call it a shuffle cipher. It shuffles up all the words, but in a very predictable manner.

As long as you know the decypher_key and the type of cipher you can recover the data quite easily just as you could with a deck of cards if you knew exactly how they were shuffled(since it's not truly random).

To make the inverse cipher you must create the opposite key. If location 0 went to 16 then that means location 16 would have to go to 0. Do this for each number in the array and form a new array called 'encrypt_key' and then you have a way to encrypt words that can be properly decrypted with the code you have given.


Lua code:

function printarray(arr) local s = '[' for k,v in pairs(arr) do s = s..tostring(v)..', '  end s = s:sub(1,-3)..']' return s end
function permute(arr, key) local newarr = {}; for i = 1, #key do newarr[i] = arr[key[i]] end return newarr end

letters = {'a','b','c','d','e'};
key = {5, 1, 3, 4, 2};
invkey = {}
newletters = permute(letters, key)
print('input:  '..printarray(letters))
print('key:    '..printarray(key))
print('output: '..printarray(newletters))


for i = 1, #key do
    for j = 1, #key do
        if i == key[j] then
            invkey[i] = j;
            break;
        end
    end
end;

newletters2 = permute(newletters, invkey)
print('\nInverse Permutation')
print('input:  '..printarray(newletters))
print('key:    '..printarray(invkey))
print('output: '..printarray(newletters2))

output:

input:  [a, b, c, d, e]
key:    [5, 1, 3, 4, 2]
output: [e, a, c, d, b]

Inverse Permutation
input:  [e, a, c, d, b]
key:    [2, 5, 3, 4, 1]
output: [a, b, c, d, e]
Sign up to request clarification or add additional context in comments.

21 Comments

This is the same point where am I. However swapping all keys in the decrypt_key will result in an array like this: [0,1,2,3,4,5...], like your rearranged array. This is why I couldn't find the reverse key. Also as Dai states, symmetrical key doesn't mean that the same algorithm have been used to encrypt the message (even if I must say it looks so), but maybe a different one has been used.
@Fire-Dragon-DoL I think you are not thinking about it hard enough. You must write the inverse permutation: I will start it off: encrypt_key = [12, 7, 18, ...]. The rearranged array is not the inverse but the result of the composition: decrypt_key[encrypt_key[k]]. k = 0 ==> decrypt_key[12] = 0. k = 1 =>> decrypt_key[7] = 1, etc... But word_to_encrypt[encrypt_key[k]] will give an permutation of the words and then when word_to_decrypt[decrypt_key[k]] will apply the inverse permutation(which is not 0 1 2 3 4 5 ...).
I simply rearranged the keys from lowest to highest so you could see that it is a permutation(there are no "gaps"). That is, if we think of k as going from 0 to 25 then decrypt_key simply makes it "out of order" but we still go from 0 to 25(just not 0 1 2 3 4 ... but 16 19 17 7 ....).
Yeah, so the array after execution is 9 8 7 6 5 4 3 2 1 0. Now, you have chosen a symmetric key so that if you run the code on itself again you'll end up with the original array. If you would have chosen, say, 5 2 6 4 9 8 3 1 7 0 then the the key to decrypt it would not be the same. e.g., our "encrypted" array is 5 2 6 4 8 9 3 1 7 0. Then our decrypted_key must be 9 7 1 6 3 0 2 8 4 5. It is not the same key. When we apply the key to the array we end up with our original array back. You must make sure you keep the data separate from the key's(the indexers). You can use letters for data...
@Fire-Dragon-DoL: yes, 26 letters has 26! ways to permutate. Again, you are making it way too difficult. If a key takes an index k to j then you just need to find how to go from the index j to k. I will give a simple example on 5 letters: (note, use a new line for each line, copy and paste into a text editor to view it better) a b c d e <- data; 5 1 3 4 2 <- permutation; b e c d a <- result; inverse permutation: b e c d a <- data; 2 5 3 4 1 <- inverse permutation; a b c d e <- result;
|
2

You don't need to reverse-engineer it: you already have the JavaScript source code. The algorithm looks simple enough (just two nested loops) - just stepping through it with a debugger should reveal how the "key" relates to any given input.

The algorithm looks symmetrical, so once you understand what they key does (it looks like it just shuffles characters around in a string according to the key), then you can derive the encryption function.

3 Comments

I thought too the key was symmetrical, however I tried re applying the key on a decrypted file and, however, I get a completely different encrypted file (notice that I have both an encrypted and encrypted file)
How did you "apply the key" to a decrypted file? Symmetrical encryption doesn't mean running the same function twice will flip between clear and ciphertext (unlike XORing), it just means that the same key can be used for both, although the encryption and decryption algorithms themselves will be different.
Mhhh... That's important, I have to work on a different algorithm... At least I won't waste other time on it. Thanks a lot for this suggestion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.