Francesco Belladonna
Francesco Belladonna

Reputation: 11689

Reverse a DECRYPT algorithm

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.

Upvotes: 0

Views: 758

Answers (2)

JonSlaughter
JonSlaughter

Reputation: 272

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]

Upvotes: 4

Dai
Dai

Reputation: 155270

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.

Upvotes: 2

Related Questions