【问题标题】:Reverse XOR function反向异或功能
【发布时间】:2021-11-03 23:50:39
【问题描述】:

我有这个功能可以解密一些东西。我想是某种密码反馈模式。

数组的第一个元素0 被异或并左移0xB 然后所有数组元素左移:

  • 1变成0,

  • 2 变成 1,

  • 3 变成 2。

接下来是一些 XOR 操作,结果变成 Array 中的新元素 4。

等等。

uint Some_function(uint *Array)                             // *Array pointer to 4*4 bytes array
    
    {
      uint Temp_1;
      uint Temp_2;
      
      Temp_1 = *Array ^ *Array << 0xb;                          // Temp_1 = XOR Array[0],Array[0] LSL 0xB (multiply by 0x800) 
      *Array = Array[1];                                        // Move Array[1] to Array[0]
      Array[1] = Array[2];                                      // Move Array[2] to Array[1]
      Temp_2 = Array[3];                                        // Load Array[3] into Temp_2
      Array[2] = Temp_2;                                        // Move Array[3] to Array[2]
      Temp_1 = Temp_2 ^ Temp_2 >> 0x13 ^ Temp_1 ^ Temp_1 >> 8;  // Temp_1 = Temp_2 XOR (Temp_2 LSR 0x13) XOR Temp_1 XOR (Temp_1 LSR 0x8)
      Array[3] = Temp_1;                                        // Move Temp_1 to Array[3]
      return Temp_1;
    }

对于解密工作正常,但我不明白如何加密。

我有(我认为是 IV)用于加密,

开头是

array[] = {0x5E9094CA, 0xB2E34CBD, 0xF9ED0B7C, 0x577C17C1}

在第一步之后变成

array[] = {0x10BF5970, 0x5E9094CA, 0xB2E34CBD, 0xF9ED0B7C}  

我想我必须对Array[3]做点什么

Move Array[2] to Array[3]

Move Array[1] to Array[2]

Move Array[0] to Array[1]

Array[3]Array[2]Array[1] 的结果做点什么?然后将结果放入Array[0]?

听起来很简单,但我看不懂。

我是个新手,所以请简单解释一下这个函数的反函数是什么。

更新
我用这个代码

        unsafe public uint Enc(ref uint[] Array)
        {
            uint[] TempArray; 
            TempArray = new uint[4];
            uint current;
            //uint Temp_1;                          not used
            uint Temp_2;
            uint term_0;
            uint term_1;
            uint term_2;
            uint term_3;
            uint shifted_bits;
            uint byteMask;
            uint encryptedByteMask;

            TempArray[1] = Array[0];
            TempArray[2] = Array[1];
            TempArray[3] = Array[2];
            term_3 = Array[3];
            Temp_2 = Array[2];
            term_2 = Temp_2 ^ Temp_2 >> 0x13;
            term_1 = term_3 ^ term_2;
            // Array[0]     0xCA94905E
            // Array[1]     0xBD4CE3B2
            // Array[2]     0x7C0BEDF9
            // Array[3]     0xC1177C57
            // term_1       0xBD1C9E2F  
            // term_2       0x7C0BE278
            current = term_1;
            for (int byteIndex = sizeof(uint) - 1 - 1; byteIndex >= 0; byteIndex--)
            {
                byteMask = (uint)(0xFF << (byteIndex * 8) + 8);         //added cast, cannot implicitly convert int to uint
                encryptedByteMask = current & byteMask;
                current = current ^ (encryptedByteMask >> 8);
             }
            // current = 0xBD1C9E2F BD^1C = A1
            // current = 0xBDA19E2F A1^9E = 3F
            // current = 0xBDA13F2F 3F^2F = 10
            // current = 0xBDA13F10
            term_0 = current;
            uint eleven_bit_mask = (1 << 12) - 1;
            uint current_0 = term_0;                                    // current_0 because current already defined on that scope
            for (int msbit = 11; msbit < sizeof(uint) * 8; msbit += 11)
            {
                shifted_bits = (current_0 & eleven_bit_mask) << 11;
                current_0 = current_0 ^ shifted_bits;
                eleven_bit_mask <<= 11;
            }
            //current_0 = 0x7019BF10 but expected was 0x7059BF10
            TempArray[0] = current_0;
            Array[0] = TempArray[0];
            Array[1] = TempArray[1];
            Array[2] = TempArray[2];
            Array[3] = TempArray[3];
            return TempArray[0];

        }

但我没有得到预期的结果。 结果值为 0x7019BF10

更新 用解决方案替换 las 部分 Simplify the inverse of Z = X ^ (X << Y) function 现在好了。

【问题讨论】:

  • 我认为 start 和 end 的值是翻转的。我假设 Some_function 方法正在加密,因为反函数更复杂,需要更多时间来执行。通常加密应该比解密更快 - 以快速保护秘密 - 并减慢暴力攻击。而且我认为 Some_function 至少被调用了 4 次,以便对过度给定的数组中的 4 个 uint 值进行正确加密。我的哪些假设是正确的?
  • Some_function 用于解密。在其他函数中,返回值与 4 字节加密数据进行异或运算,结果解密 4 字节。然后在下一次调用中解密另外 4 个字节的加密数据。解密部分的时间很重要,Some_function 被调用超过 10000 次。

标签: encryption reverse xor


【解决方案1】:

我认为 start 和 end 的值是颠倒的。我假设 Some_function 方法正在加密,因为反函数更复杂,需要更多时间来执行。通常加密应该比解密更快 - 以快速保护秘密 - 并减慢暴力攻击。 (而且我猜 Some_function 至少被调用了 4 次,以正确加密过度给定数组中的 4 个 uint 值)。

有了这些假设,这是我的解决方案:

因为我(以及我猜的许多其他程序员)不喜欢看到变量通过算法获得不同的值,所以我对其进行了调整, 变量大多从不改变它们的值。 此外,更多变量简化了逆(解密)算法的解释,我重新排列了它以便于理解:

uint encrypt(uint *Array)                             // *Array pointer to 4*4 bytes array
    
    {
      unit* decrypted = Array;
      uint Temp_1;
      uint Temp_2;
      uint term_0;
      uint term_1;
      uint term_2;
      
      Temp_1 = decrypted[0];
      term_0 = Temp_1 ^ Temp_1 << 0xb;  // Temp_1 = XOR Array[0],Array[0] LSL 0xB (multiply by 0x800) 
      Temp_2 = decrypted[3];
      term_1 = term_0 ^ term_0 >> 8;
      term_2 = Temp_2 ^ Temp_2 >> 0x13
      term_3 = term_2 ^ term_1;

      // encrypted[x] = decrypted[y]
      Array[0] = Array[1];
      Array[1] = Array[2];
      Array[2] = Array[3];
      Array[3] = term_3;

      return term_3;
    }
    
void decrypt(uint *Array)
{
  uint* encrypted = Array;
  uint[4] decrypted; // buffer variables to better know whether a value is now decrypted or not
  uint current;
  uint Temp_1;
  uint Temp_2;
  uint term_0;
  uint term_1;
  uint term_2;
  uint shifted_bits;
  uint byteMask;
  uint encryptedByteMask;

  decrypted[1] = encrypted[0];
  decrypted[2] = encrypted[1];
  decrypted[3] = encrypted[2];
  
  // reverse of line
  // term_3 = term_2 ^ term_1
  // term_3 is known, it is encrypted[3]
  term_3 = encrypted[3];
  // term_2 = Temp_2 ^ Temp_2 >> 0x13 is known because Temp_2 is known = decrypted[3] = encrypted[2]
  Temp_2 = encrypted[2];
  term_2 = Temp_2 ^ Temp_2 >> 0x13;
  // so we know term_3 and term_2, but term_1 not - from "term_3 = term_2 ^ term_1", therefore
  term_1 = term_3 ^ term_2;
  // but term_1 = Temp_1 ^ Temp_1 >> 8, and would like to know Temp_1
  // bit position
  //               6666555555555544444444443333333333 - bit position * 10 +
  //               3210987654321098765432109876543210 - bit position *  1
  // Temp_1      = abcdefghijklmnopqrstuvwxyz...
  // Temp_1 >> 8 = 00000000abcdefghijklmnopqr...
  // term_1 =      abcdefgh????????...
  //               \------/ => these 8 most significant bits are identical in Temp_1 and term_1
  //                       \------/ => these 8 bits in term_1 XOR with the bits abcdefgh will result in ijklmnop!
  // and using ijklmnop 8 bits to the right, ... and so on we can decrypt term_1 completely to Temp_1.
  
  // so the highest significant byte of Temp_1 is not xor-ed, so it is decrypted
  // if we xor it with the 2nd most significant byte, we get the decrypted value of the 2nd highest byte of Temp_1 and so on...
  current = term_1;
  for (int byteIndex = sizeof(uint) - 1 - 1; byteIndex--; byteIndex >= 0)
  {
    byteMask = 0xFF << (byteIndex * 8 + 8);
    encryptedByteMask = current & byteMask;
    current = current ^ (encryptedByteMask >> 8);
  }
  term_0 = current;
  // now term_0 has the value of the right side of "term_0 = Temp_2 ^ Temp_2 >> 0x13 ^ Temp_1 ^ Temp_1 >> 8;"
  // now we want to reverse "term_0 = Temp_1 ^ Temp_1 << 0xb; "
  // to get Temp_1 = *Array, or Array[0] = decrypted[0]
  // again because of left shift, the rightest (or least significant) 11 bits of Temp_1 are unmodified(LSB) (bit position 0 to 10)
  // the next 11 bits (positon 11 to 21) are xor-ed with bits from position 0 to 10 -
  // if we xor them again. the positon 11 to 21 are resolved too!
  uint eleven_bit_mask = (1 << 12) - 1;
  uint current = term_0;
  for (int msbit = 11; msbit += 11; msbit < sizeof(uint) * 8)
  {
    shifted_bits = (current & eleven_bit_mask) << 11;
    current = current ^ shifted_bits;
    eleven_bit_mask <<= 11;
  }
  decrypted[0] = current;
  
  // adapt overgiven array
  Array[0] = decrypted[0];
  Array[1] = decrypted[1];
  Array[2] = decrypted[2];
  Array[3] = decrypted[3];

  return;
}

这里是运行的 Python 版本(0xFFffFFff 用于限制为 uint 值):

# Solution as python
# 

decrypted = [0x10BF5970, 0x5E9094CA, 0xB2E34CBD, 0xF9ED0B7C] # array before Some_function
encrypted = [0x5E9094CA, 0xB2E34CBD, 0xF9ED0B7C, 0x577C17C1] # array after Some_function
array = decrypted[:]

def encrypt(array):  # Some_Function from https://stackoverflow.com/questions/69790684/reverse-xor-function/69791006#69791006
      Temp_1 = array[0] ^ ((array[0] << 0xb) & 0xFFffFFff) #    // Temp_1 = XOR array[0],array[0] LSL 0xB (multiply by 0x800) 
      array[0] = array[1] #                                       // Move array[1] to array[0]
      array[1] = array[2] #                                      // Move array[2] to array[1]
      Temp_2 = array[3] #                                       // Load array[3] into Temp_2
      array[2] = Temp_2 #                                        // Move array[3] to array[2]
      Temp_1 = Temp_2 ^ (Temp_2 >> 0x13) ^ Temp_1 ^ (Temp_1 >> 8) # Temp_1 = Temp_2 XOR (Temp_2 LSR 0x13) XOR Temp_1 XOR (Temp_1 LSR 0x8)
      array[3] = Temp_1#                                        // Move Temp_1 to array[3]
      return Temp_1

def decrypt(array):
  encrypted = array[:]
  decrypted = array[:]
  
  decrypted[1] = encrypted[0]
  decrypted[2] = encrypted[1]
  decrypted[3] = encrypted[2]
  
  # reverse of 
  # Temp_1 = Temp_2 ^ Temp_2 >> 0x13 ^ Temp_1 ^ Temp_1 >> 8;
  # Temp_1 right of '=' is unknown, 
  # but Temp_2 is known, it is in decrypted[3]
  # Temp_1 left of '=' is known, it is encrypted[3]
  # so (Temp_2 ^ Temp_2 >> 0x13) can be calculated
  temp2modified = decrypted[3] ^ decrypted[3] >> 0x13
  # we know the left Temp_1 = encrypted[3], but we do not know yet (^ Temp_1 ^ Temp_1 >> 8) on the right side,
  # but this is:
  temp1right = encrypted[3] ^ temp2modified
  # now temp1right = Temp_1 ^ Temp_1 >> 8 -->  we look for Temp_1 in this expression:
  # so the highest Byte of Temp_1 is not xor-ed, so it is undecrypted
  # if we xor it with the 2nd most significant byte, we get the encrypted value of the 2nd highest byte of Temp_1 and so on...
  Temp_1 = temp1right
  for byteIndex in range(2, -1, -1):
      byteMask = (0xFF << (byteIndex * 8 + 8)) & 0xFFffFFff
      encryptedByteMask = Temp_1 & byteMask
      Temp_1 = Temp_1 ^ (encryptedByteMask >> 8)

  # now Temp1 has the value of the right side of "Temp_1 = Temp_2 ^ Temp_2 >> 0x13 ^ Temp_1 ^ Temp_1 >> 8;"
  # now we want to reverse "Temp_1 = *Array ^ *Array << 0xb; ", we know now Temp_1
  # to get *Array, or Array[0] = decrypted[0]
  # again because of left shift, the rightest 11 bits of Temp_1 are unmodified(LSB) (bit position 0 to 10)
  # the next 11 bits (positon 11 to 21) are xor-ed with bits from position 0 to 10 -
  # if we xor them again. the positon 11 to 21 are resolved too!
  eleven_bit_mask = (1 << 12) - 1
  Array0 = Temp_1
  for msbit in range(11, 64, 11):
    shifted_bits = ((Array0 & eleven_bit_mask) << 11) & 0xFFffFFff
    Array0 = Array0 ^ shifted_bits
    eleven_bit_mask <<= 11

  decrypted[0] = Array0
  
  # adapt overgiven array
  array[0] = decrypted[0]
  array[1] = decrypted[1]
  array[2] = decrypted[2]
  array[3] = decrypted[3]

  return

def hex_dump(array):
    return f'{array[0]:#02x}, {array[1]:#02x}, {array[2]:#02x}, {array[3]:#02x}'

result_encrypt = encrypt(array)

print(f'input before encryption: {hex_dump(decrypted)}')
print(f'after Some_funciont:     {hex_dump(array)} (encrypted)')
print(f'expected encrypted:      {hex_dump(encrypted)}')
print(f'retured value = {result_encrypt}')

before_decrypt = array[:]
result_decrypt = decrypt(array) # or inverse function that is searched for by gabiz
print(f'input before decryption: {hex_dump(before_decrypt)}')
print(f'after inverse/decrypt:   {hex_dump(array)} (decrypted)')
print(f'expected decrypted:      {hex_dump(decrypted)}')

# Output:
# input before encryption: 0x10bf5970, 0x5e9094ca, 0xb2e34cbd, 0xf9ed0b7c
# after Some_funciont:     0x5e9094ca, 0xb2e34cbd, 0xf9ed0b7c, 0x1373b9e8 (encrypted)
# expected encrypted:      0x5e9094ca, 0xb2e34cbd, 0xf9ed0b7c, 0x577c17c1
# retured value = 326351336
# input before decryption: 0x5e9094ca, 0xb2e34cbd, 0xf9ed0b7c, 0x1373b9e8
# after inverse/decrypt:   0x10ff5970, 0x5e9094ca, 0xb2e34cbd, 0xf9ed0b7c (decrypted)
# expected decrypted:      0x10bf5970, 0x5e9094ca, 0xb2e34cbd, 0xf9ed0b7c

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多