我想问一下您是否有任何想法或方法对解密算法进行反向工程以找到相反的加密功能。
我确实拥有所有必需的密钥和字段,当然还有解密源代码,我已经对其进行了反向工程。

我已经分析了代码,并且有点知道它是如何工作的,但是无法弄清楚如何反向(在取消加密的意义上)。

以下信息可供我使用:

// I have all these fields (filled correctly)

    public byte[] Keychain;
    public uint Step, Mul, HeaderXor, Key;


解密功能如下:

public void Decrypt(byte[] packet) {
        fixed (byte* pp = packet, pk = Keychain) {
            uint size = (uint)GetPacketSize(packet);
            uint header = (first) ? /* Checks if it is a partial packet (It isnt!)*/
                0x000eb7e2 :
                *((uint*)&pp[0]) ^ HeaderXor; 
                // HeaderXor is an unsigned int
                // It also changes after each decryption and if the key changes

            if (first) 
                first = false;

            uint token = *((uint*)&pp[0]);
            *((uint*)&pp[0]) = header;
            token &= 0x3FFF;    // Get only last 14 bits
            token *= Mul * 4;   
            // Mul is an unsigned int and changes sometimes
            token = *((uint*)&pk[token]);

            uint i, r, t;
            size -= r = (size - 8) & 3; // Make size dividable by 4

            for (i = 8; i < size; i += 4) {
                t = *((uint*)&pp[i]);
                token ^= t;
                *((uint*)&pp[i]) = token;

                t &= 0x3FFF;
                token = *((uint*)&pk[t * Mul * 4]);
            }

            t = 0xFFFFFFFF >> 8 * (4 - (int)r);
            token &= t;
            *((uint*)&pp[i]) ^= token; // If something is left over ( if size - 8 == 5 then size & 3 has rest of 1)
            * ((uint*)&pp[4]) = 0;

            Step++;
            Step &= 0x3FFF;
            HeaderXor = *((uint*)&pk[Step * Mul * 4]);
        }
    }


示例结果:

// Encrypted data
// 5b 54 34 23
// cc c2 5a a3
// 81 7e d6 27
// 36 c4 8f 36
// b9 3b 6f ce
// f4 8e 72 5b
// 
// Decrypted data
// e2 b7 18 00
// 00 00 00 00
// be 00 56 00
// 2f 00 58 00
// 30 00 59 00
// 31 00 01 00


那么,您有什么办法吗?
也许此源代码可以提供更多信息,但是它的服务器到客户端: />
https://bitbucket.org/dignityteam/minerva/src/e149a219b6783070de71820ea359f1b27cebda63/src/ObjectBuddy/Cryption.cs?at=develop&fileviewer=file-view-default

我认为,服务器到客户端的加密不是正确的选择。我上面发布的解密代码确实返回了正确的结果,但是与链接页面上看到的结果不同。

#1 楼

好消息,您很幸运!

面对的是流密码。为什么这么好?因为流密码的构建方式使它们极其容易反转-流密码的解密和加密功能实际上是相同的功能。


流密码是对称密钥密码,其中明文数字与伪随机密码数字流(密钥流)组合在一起。在流密码中,每个明文数字每次都用密钥流的相应数字加密一次,以给出密文流的数字。由于每个数字的加密取决于密码的当前状态,因此也称为状态密码。实际上,一个数字通常是一个位,而组合操作通常是异或(XOR)。字节几乎逐字节地与消息混合,几乎总是使用XOR操作。您的函数也是如此,请参见token ^= t;行。由于两个具有相同值的XOR操作会互相抵消,因此在接收端再次对具有相同流的加密消息的字节进行XOR运算实际上将对其解密。要首先生成流,只需再次应用相同的功能即可为您提供原始消息。

评论


感谢您提供这些信息。我将尝试在此解密数据上运行相同的功能。我会告诉你最新的。

–bitQUAKE
16年9月10日在21:19

嗨,我试图将其转换回去。完全正确,这些密码算法确实使用相同的算法进行加密/解密。但就我而言,服务器和客户端之间的密钥正在快速变化。我使用了解密算法来重建下一个密钥,现在效果很好:)

–bitQUAKE
16/09/13在18:31



流密码必须彼此同步才能被接收,它们将在两端产生相同的序列。这可以通过以下方式完成:-)发送消息同步,或b)根据先前的位置猜测并尝试多个值。如果您对N编辑感兴趣,我可以详细说明

– NirIzr
16/09/13在18:35



您的意思是:如果您对N edit感兴趣,我可以详细说明一下? :)

–bitQUAKE
16/09/13在18:42

抱歉,进行修改。我的意思是我可以编辑答案并添加有关该信息的更多信息

– NirIzr
16/09/13在18:44